ORM
对象关系映射,把类当成数据库中的表,把类对象当做数据库中的数据,每一个对象就对应表中没有每一条数据,通过对象.属性的方式,获取每条数据的字段值
需要用的知识点
面向对象,单利模式,元类
sql.py 文件
import pymysql
dic = {
'host': '127.0.0.1',
'port': 3306,
'user': 'root', # 用户名
'passwd': 'root', # 密码
'db': 'day41', # 数据库
'charset': 'utf8',
'autocommit': True,
}
class Mysql(object):
_instance = None
def __init__(self):
self.conn = pymysql.connect(**dic)
self.corsur = self.conn.cursor(pymysql.cursors.DictCursor)
def close_db(self):
self.corsur.close()
self.conn.close()
def select(self, sql, args=None):
self.corsur.execute(sql, args)
res = self.corsur.fetchall()
return res
def execute(self, sql, args):
try:
self.corsur.execute(sql, args)
except BaseException as e:
print(e)
@classmethod
def singleton(cls):
if not cls._instance:
cls._instance = cls()
return cls._instance
orm.py 文件
from sql import Mysql
class Field(object):
def __init__(self, name, column_type, primary_key, default):
self.name = name
self.column_type = column_type
self.primary_key = primary_key
self.default = default
class StringField(Field):
def __init__(self, name, column_type='varchar(32)', primary_key=False, default=None):
super().__init__(name, column_type, primary_key, default)
class IntegerField(Field):
def __init__(self, name, column_type='int', primary_key=False, default=None):
super().__init__(name, column_type, primary_key, default)
class MateClass(type):
def __new__(cls, name, obj, attr):
if name == 'Models':
return type.__new__(cls, name, obj, attr)
table_name = attr.get('table_name', name)
primary_key = None
mappings = {}
for k, v in attr.items():
if isinstance(v, Field):
if v.primary_key:
if primary_key:
raise TypeError('just have a primary key')
primary_key = v.name
for k in mappings.keys():
cls.attr.pop(k)
if not primary_key:
raise TypeError('must have a primary key')
attr['table_name'] = table_name
attr['primary_key'] = primary_key
attr['mappings'] = mappings
return type.__new__(cls, name, obj, attr)
class Models(dict, metaclass=MateClass):
def __init__(self, **kws):
super().__init__(**kws)
def __getattr__(self, item):
return self.get(item, 'not found key')
def __setattr__(self, key, value):
self[key] = value
@classmethod
def select(cls, **kws):
ms = Mysql.singleton()
if not kws:
sql = 'select * from %s' % (cls.table_name)
res = ms.select(sql)
else:
k = list(kws.keys())[0]
v = kws.get(k)
sql = 'select * from %s where %s = ? ' % (cls.table_name, k)
sql = sql.replace('?', '%s')
res = ms.select(sql, v)
if res:
return [cls(**r) for r in res]
class Teacher(Models):
table_name = 'teacher'
tid = IntegerField(name='tid', primary_key=True)
tname = StringField(name='tname')
class Course(Models):
table_name = 'course'
cid = IntegerField(name='cid', primary_key=True)
cname = StringField(name='cname')
teacher_id = IntegerField(name='teacher_id')
class Score(Models):
table_name = 'score'
sid = IntegerField(name='sid', primary_key=True)
student_id = IntegerField(name='student_id')
course_id = IntegerField(name='course_id')
num = IntegerField(name='num')
class Student(Models):
table_name = 'student'
tid = IntegerField(name='tid', primary_key=True)
gender = StringField(name='gender', column_type='varchar(1)')
class_id = IntegerField(name='class_id')
sname = StringField(name='sname', column_type='varchar(5)')
if __name__ == '__main__':
s = Student.select(sid=1)
print(s)
t = Teacher.select(tid=1)
print(t)
初级版本 待更新