当前位置: 首页 > 后端技术 > Python

使用SQL超方便的Python神器

时间:2023-03-26 17:48:26 Python

一开始其实用的是pymysql,但是发现维护起来比较麻烦,还有代码注入的风险,所以索性直接用了ORM框架。ORM全称ObjectRelationalMapper,可以简单理解为数据库表和Python类之间的映射。通过操作Python类,可以间接操作数据库。Python的ORM框架比较有名的有SQLAlchemy和Peewee。这里不做对比,只是简单说明一下个人对SQLAlchemy的一些使用,希望能给朋友们带来帮助。sqlalchemyversion:1.3.15pymysqlversion:0.9.3mysqlversion:5.7初始化工作一般使用ORM框架,会有一些初始化工作,比如数据库连接,定义基本映射等,以MySQL为例,你只需要需要传入DSN字符串来创建数据库连接。其中echo表示是否输出相应的SQL语句,有助于调试。fromsqlalchemyimportcreate_engineengine=create_engine('mysql+pymysql://$user:$password@$host:$port/$db?charset=utf8mb4',echo=True)对于我个人的设计,在引入ORM框架的时候,我的项目将参考MVC模式做如下设计。其中,model存放了一些数据库模型,即映射到数据库表的Python类;model_op存储了每个模型对应的操作,即增删改查;当调用者(如main.py)进行数据库操作时,只需要调用model_op层,不用关心model层,从而达到解耦。├──main.py├──model│├──__init__.py│├──base_model.py│├──ddl.sql│└──py_orm_model.py└──model_op├──__init__.py└───py_orm_model_op.pymappingdeclaration(Modelintroduction)比如我们有这样一个测试表createtablepy_orm(`id`int(11)NOTNULLAUTO_INCREMENTCOMMENT'uniqueid',`name`varchar(255)NOTNULLDEFAULT''COMMENT'name',`attr`JSONNOTNULLCOMMENT'attribute',`ct`timestampNOTNULLDEFAULTCURRENT_TIMESTAMPCOMMENT'createdtime',`ut`timestampNOTNULLDEFAULTCURRENT_TIMESTAMPONupdateCURRENT_TIMESTAMPCOMMENT'updatedtime',PRIMARYKEY(`id`))ENGINE=InnoDBCOMMENT'测试表';在ORM框架中,映射的结果是下面的Python类Integer,autoincrement=True,primary_key=True,comment='uniqueid')name=Column(String(255),nullable=False,=fa',comment='name')attr=Column(JSON,nullable=False,comment='attribute')ct=Column(TIMESTAMP,nullable=False,server_default=text('CURRENT_TIMESTAMP'),comment='creationtime')ut=Column(TIMESTAMP,nullable=False,server_default=text('CURRENT_TIMESTAMPONUPDATECURRENT_TIMESTAMP'),comment='UpdateTime')首先我们可以看到PyOrmModel继承了Base类,这是sqlalchemy提供的一个基类,会对我们声明的Python类做一些检查,我把它放在base_model#base_model.py#一般base_model做一些初始化工作fromsqlalchemyimportcreate_enginefromsqlalchemy.ext.declarativeimportdeclarative_baseBase=declarative_base()engine=create_engine("mysql+pymysql://root:123456@127.0.0.1:33306/orm_test?charset=utf8mb4",echo=False)其次,每个Python类都必须包含__tablename__属性,否则找不到对应的表。三、创建数据表有两种方式。第一种当然是在MySQL中手动创建。只要你的Python类定义没有问题,就可以正常运行;二是通过orm框架创建,比如下面的#main.py#注意这里的导入路径。Base在创建表的时候,会寻找继承它的子类。如果路径错误,将无法创建成功。fromsqlachlemy_labimportBase,engineif__name__=='__main__':Base.metadata.create_all(engine)创建效果:...2020-04-0410:12:53,974INFOsqlalchemy.engine.base.EngineCREATETABLEpy_orm(idINTEGERNOTNULLAUTO_INCREMENT,nameVARCHAR(255)NOTNULLDEFAULT''COMMENT'name',attrJSONNOTNULLCOMMENT'property',ctTIMESTAMPNOTNULLDEFAULTCURRENT_TIMESTAMP,utTIMESTAMPNOTNULLDEFAULTCURRENT_TIMESTAMPONUPDATECURRENT_TIMESTAMP,ctPRIMARYKEY(primarykey)是mysql的主键和auprimary(字段_cremary的比较)和auprimary)。增加财产。2、如果是int类型,则不需要指定长度,如果是varchar类型,则必须指定。3.Nullable对应MySQL中的NULL和NOTNULL4.关于default和server_default:default表示ORM框架层面的默认值,即如果插入时字段没有赋值,我们定义的默认值为用过的;server_default表示数据库级别的默认值,即DDL语句中的default关键字。Session的介绍在SQLAlchemy的文档中有提到,对数据库的增删改查都是通过session进行的。从sqlalchemy.orm导入sessionmakerSession=sessionmaker(bind=engine)session=Session()orm=PyOrmModel(id=1,name='test',attr={})session.add(orm)session.commit()session。close()如上,我们可以看到对于每一个操作,我们都需要获取、提交和释放session。这样就太多余了,也太麻烦了,所以我们一般都会进行一层封装。1、使用contextmanager处理session的异常回滚和关闭,和参考文章几乎一致。#base_model.pyfromcontextlibimportcontextmanagerfromsqlalchemy.ormimportsessionmaker,scoped_sessiondef_get_session():"""Getsession"""returnscoped_session(sessionmaker(bind=engine,expire_on_commit=False))()#这里统一管理,包例如获取,提交,@contextmanagerdefdb_session(commit=true):session=_get_session()try:sessionsession.commit(session.commit()excess.commit()extectextectaextescionase:session.rollback(session.rollback().close()2.model和dict转换在PyOrmModel中添加两个方法用于model和dict之间的转换classPyOrmModel(Base):...@staticmethoddeffields():return['id','name','attr']@staticmethoddefto_json(model):字段=PyOrmModel.fields()json_data={}for字段中的字段:json_data[字段]=model.__getattribute__(字段)返回json_datadef@static_dataict):fields=PyOrmModel.fields()model=PyOrmModel()forfieldinfields:iffieldindata:iffieldindata:和我文章的操作model.__setattr__(field,data[field]modelre直接调用session,让调用者不需要关注model层,降低耦合#py_orm_model_op.pyfromsqlachlemy_lab.model导入db_sessionfromsqlachlemy_lab.model导入pyormmmodelclclasspyormmodelop:def__init__Init__(self):pass@staticmethoddef_data:save_data(dec)add(model)#查询操作,不需要提交@staticmethoddefquery_data(pid:int):data_list=[]withdb_session(commit=False)assession:data=session.query(PyOrm)..filter(PyOrm)=数据中的d数据:data_list.append(pyormmodel.to_json(d))返回data_list4。,'name':'test','attr':{}})以上就是本次分享的所有内容,如果你觉得文章还不错,欢迎关注公众号:Python编程学习圈,每日干货分享,“J”还可以领取大量学习资料,内容覆盖Python电子书、教程、数据库编程、Django,熊猫,云计算等。或者是往编程学习网,了解更多。

最新推荐
猜你喜欢