ORM——对象关系映射01

该博客主要围绕数据库操作展开,包含数据库连接代码,使用 pymysql 库连接 MySQL 数据库。还给出 ORM 代码,定义了字段的父类及字符串、整型类型字段类,同时有辅助类方便实例化对象调用属性,最后给出了一个 Teacher 类示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数据库连接

import pymysql

class Mysql(object):
_instance = None
def init(self):
self.conn = pymysql.connect(
host = '127.0.0.1',
port = 3306,
user = 'root',
password = '',
database = 'day41',
charset = 'utf8',
autocommit = True
)
self.cursor = self.conn.cursor(pymysql.cursors.DictCursor)
def close_db(self):
self.cursor.close()
self.conn.close()

def select(self,sql,args=None):
    self.cursor.execute(sql,args)
    res = self.cursor.fetchall()  # 注意一点:fetchall拿到的数据结构是一个列表套字典[{},{},{}]
    return res

def execute(self,sql,args):
    # insert into user(name,password) values('jason','123')
    # update user set name='jason',passsword='456' where id=1
    try:
        self.cursor.execute(sql, args)
    except BaseException as e:
        print(e)

@classmethod
def singleton(cls):
    if not cls._instance:
        cls._instance = cls()
    return cls._instance

ORM 代码

from mysql_signleton import Mysql

定义字段的父类,参数包括:字段名,类型,主键,默认值

class Field(object):
def init(self, name, colum_type, primary_key, default):
self.name = name
self.colum_type = colum_type
self.primary_key = primary_key
self.default = default

定义字符串类型的字段类

class StringField(Field):
def init(self, name, colum_type='varchar(32)', primary_key=False, default=None):
super().__init__(name,colum_type,primary_key,default)

定义整型了类型字段

class IntField(Field):
def init(self,name,colum_type='int',primary_key = False, default = None):
super().__init__(name,colum_type,primary_key,default)

class MyMetaClass(type):
def new(cls,class_name,class_bases,class_attrs):
# 定义的元类的是用来拦截modle的创建过程,modles并不是一个模型表,不需要创建过程
if class_name =='Modles':
return type.__new__(class_name,class_bases,class_attrs)
# 创建一个表,如果有新表名就用表名,没有就默认用类名
table_name = class_attrs.get('table_name',class_name)
primary_key = None
mappings = {}

    for k,v in class_attrs.items(): # k: id,name v:IntField(),StringField()
        # 拿出所有自定义的表的字段属性
        if isinstance(v,Field):
            # 将所有的自定义的表的字段存入字典中
            mappings[k]=v
            # 检验表的主键
            if v.primary_key:
                # 每个表只有一个主键
                if primary_key:
                    raise TypeError('一张表只有一个属性')
                primary_key = v.name

    for k in mappings.keys():
        # 将单个字段删除
        class_attrs.pop(k)
    # 检验用户自定义模型表是否指定主键字段
    if not primary_key:
        raise TypeError('一张表必须要有主键')
    # 将标示表的特征信息,表名,表的主键字段,表的其他字段都塞到类的名称空间中
    class_attrs['table_name'] = table_name
    class_attrs['primary_key'] = primary_key
    class_attrs['mapping'] = mappings
    return type.__new__(cls,class_name,class_bases,class_attrs)

辅助类:方便实例化对象使用点方法,直接调用属性

class Modles(dict, metaclass=MyMetaClass):
# 继承字典的方法
def init(self,**kwargs):
super().__init__(**kwargs)

# 获取字典对应的值self = 字典
def __getattr__(self, item):
    return self.get(item,'没有该键')

# 修改属性值
def __setattr__(self, key, value):
    self[key] = value


@classmethod
def select(cls,**kwargs):
    ms = Mysql.singleton()

    if not kwargs:
        sql = 'select * from %s'%cls.table_name
        res = ms.select(sql)

    else:
        k = list(kwargs.keys())[0] # .keys 不能直接取值,可以迭代取值
        v = kwargs.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]

if name == 'main':
class Teacher(Modles):
table_name = 'teacher'
tid = IntField(name='tid', primary_key=True)
tname = StringField(name='tname')

t1 = Teacher(tname='king',tid=1)
print(t1.tname)
print(t1.tid)

转载于:https://www.cnblogs.com/king-home/p/10897141.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值