资讯动态

python中ORM框架使用

发布时间:2026/8/31 4:53:50 来源:尧图企业网站定制
Flask-SQLAlchemy扩扩展展的的配配置置与与使使用在 Flask 中所有扩展插件基本上都是以 Flask-Xxx 进行命名 Flask-SQLAlchemy 就是一个为 Flask 应用增加 SQLAlchemy 支持的扩展致力于简化在 Flask 中 SQLAlchemy 的使用而 SQLAlchemy 是目前 Python 中最强大的 ORM 框架功能全面使用简单。文档资料Flask-SQLAlchemy 文档https://flask-sqlalchemy.palletsprojects.com/en/3.1.x/SQLAlchemy 文档https://www.sqlalchemy.org/ORM是什么ORM 其实是 对象映射关系(Object-Relational Mapping) 即将数据库中的表与面向对象编程中的类关联起来它把数据库中的表映射为类表中的行映射为类的实例表中的列映射为类的属性。这样一来就可以通过对类的操作来进行数据库的增删改查而不必直接操作数据库让程序员更加专注于业务逻辑减少了与数据库交互的复杂性。例如有一张基础表为 account 字段信息如下CREATETABLEaccount(iduuidNOTNULL,namevarchar(255)NOTNULL,emailvarchar(255)NOTNULL,avatarvarchar(255)NOTNULL,passwordvarchar(255)NOTNULL,updated_attimestamp(6)NOTNULL,created_attimestamp(6)NOTNULL,)将其映射到 Python 的 Class 为class Account(db.Model): __tablename__account__table_args__(PrimaryKeyConstraint(id,namepk_account_id),Index(idx_account_email,email),)idColumn(UUID,defaultuuid.uuid4,nullableFalse)nameColumn(String(255),default,nullableFalse)emailColumn(String(255),default,nullableFalse)avatarColumn(String(255),default,nullableFalse)passwordColumn(String(255),default,nullableFalse)updated_atColumn(DateTime,defaultdatetime.now,onupdatedatetime.now,nullableFalse)created_atColumn(DateTime,defaultdatetime.now,nullableFalse)这样在 Python中只需要对映射类进行特定方法的调用即可实现数据数据库的增删改查写成伪代码示例如下# 类映射伪代码accountAccount(idxxx-xxx-xxx-xxx)account.add()# 增:映射到sql中的 create table xxx (xxx, xxx, xxx);account.delete()# 删:映射到sql中的 delete from xxx where xxx;account.update()# 改:映射到sql中的 update table set xxxxxx, xxxxxx where xxx;account.get()# 查:映射到sql中的 select * from xxx where xxx;通过 ORM 可以在代码中少写甚至不写 SQL去实现数据库的增删改查等 复杂业务同时确保 SQL 安全不被注入。从上面可以看出 ORM的优缺点其实非常明显优点有语法提示省去自己拼写 SQL保证 SQL 语法的正确性ORM 提供方言功能dialect可以转换为多种数据库语法减少学习成本与迁移数据库的成本面向对象可读性强开发效率高防止 sql 注入攻击搭配数据库迁移更新数据库方便缺点需要语法转换效率比原生 sql 低复杂的查询往往语法比较复杂可以使用原生 sql 代替安装 Flask-SQLAlchemy使用 pip 可以直接安装 Flask-SQLAlchemy命令如下pipinstallflask-sqlalchemy期间如果提示 ModuleNotFoundError: No module named ‘psycopg2’ 是因为使用 Postgres 作为数据库但是缺少驱动引擎导致的安装上对应的驱动引擎即可命令如下pipinstallpsycopg2也可以一次性安装两个命令pipinstallflask-sqlalchemy psycopg2和其他的 Flask 扩展一样几乎绝大部分扩展都需要进行初始化与配置Flask-SQLAlchemy 也一样并且Flask-SQLAlchemy 的的相关配置也也封装到了 Flask 的的配置项中可以通过 app.config 配置或配置加载方案config.from_object进行设置。SQLALCHEMY的主要配置如下配置项说明示例SQLALCHEMY_DATABASE_URI设置数据库的连接地址postgresql://root:123456127.0.0.1:5432/test31SQLALCHEMY_BINDS访问多个数据库时用于设置数据库的连接地址{“other_db”: “sqlite:///other.db”}SQLALCHEMY_ECHO是否打印底层执行的 SQL 语句TrueSQLALCHEMY_RECORD_QUERIES是否记录执行的查询语句, 用于慢查询分析, 调试模式下自动启动FalseSQLALCHEMY_TRACK_MODIFICATIONS是否追踪数据库变化(触发钩子函数), 会消耗额外的内存FalseSQLALCHEMY_ENGINE_OPTIONS设置针对 sqlalchemy 本体的配置项SQLALCHEMY_POOL_SIZE: 连接池最大数量 SQLALCHEMY_POOL_RECYCLE: 单个连接最长生命周期要从 Flask 中将配置信息加载到 Flask-SQLAlchemy可以使用 db.init(flask_app) 即可。ORM 模型的创建与增删改查创建模型要想在项目中使用 ORM必须创建对应的类并继承 db.Model 即可实现与对应数据库进行关联。在类中还可以通过tablename属性来设置 表名 通过 __table_args__unique索引 等约束。其中关于 ORM 模型的字段类型、索引约束、主键等均可以从 sqlalchemy 包中导入从这个包导入的类支持所有的数据库在切换数据库时不需要进行调整除此之外还可以导入特定数据库特有的结构例如Postgres 中特有的 JSONB 数据类型特有的类型在切换数据库时需要修改代码进行调整。一些常见的 sqlalchemy 的数据类型fromsqlalchemyimport(Column,# 用户定义字段UUID,# UUID类型例如123e4567-e89b-12d3-a456-426655440000String,# 字符串对应数据库的 varcharText,# 长文本类型对应数据库的 textDateTime,# 时间类型对应数据库的 timestampInteger,# 整形对应数据库的 intDecimal,# 小数型对应数据库的 decimalPrimaryKeyConstraint,# 创建主键约束Index,# 创建索引UniqueConstraint,# 创建唯一值约束)fromsqlalchemy.dialects.postgresqlimportJSONB# postgres 特有的 jsonb 数据使用二进制存储 json性能更强完整示例importuuidfromdatetimeimportdatetimefromsqlalchemyimport(Column,UUID,String,DateTime,PrimaryKeyConstraint,Index,)fromsqlalchemy.dialects.postgresqlimportJSONBfrominternal.extension.database_extensionimportdb class App(db.Model):AI应用模型tablenameapp table_args(PrimaryKeyConstraint(id ,namepk_app_id),Index(idx_app_account_id ,account_id),)idColumn(UUID,defaultuuid.uuid4,nullableFalse)account_idColumn(UUID,nullableFalse)nameColumn(String(255),default,nullableFalse)iconColumn(String(255),default,nullableFalse)configColumn(JSONB,default{},nullableFalse)updated_atColumn(DateTime,defaultdatetime.now,onupdatedatetime.now,nullableFalse)created_atColumn(DateTime,defaultdatetime.now,nullableFalse)创建完模型后可以通过调用db.create_all()在对应的数据库中创建相应的模型表例如fromflaskimportFlaskfrominternal.modelimportAppclassHttp(Flask):def__init__():...withself.app_context():_App()db.create_all()...新增数据在Flask-SQLAlchemy 中有两种主要的方式来执行数据库查询使用db.session.query (Model).xxx这种方法使用SQLAlchemy 原生查询语法来操作数据库可以使用.query 来访问一个表的查询然后使用.xxx 来指定你要执行的这种方法更加灵活可以用于复杂的查询需求。也可以使用ORM 模型的查询每个继承db.Model 的模型都有一个query 属性可以通过这个属性来执行查询例如App .query .filter() 等。# 使用db.session.query.xxx 的方式fromyourappimportdbfromyourapp.modelsimportUser# 查询所有用户并按照ID升序排列usersdb.session.query(User).order_by(User.id).all()# 查询用户名为john 的用户userdb.session.query(User).filter_by(usernamejohn ).first()# 使用ORM 模型的方式fromyourapp.modelsimportUser# 查询所有用户并按照ID升序排列usersUser.query.order_by(User.id).all()# 查询用户名为john 的用户userUser.query.filter_by(usernamejohn ).first()在项目中我们约定无论是单表、多表、简单亦或者复杂的操作均使用db.session.query.xxx 的方式进行操作确保业务逻辑的统一性。如果想要往表里添加数据只需依次调用add(model) 和.commit() 即可示例defdemo():# 实例化Students 模型对象userStudents(nameyy ,fullnameyoyo )# 添加到会话并用commit提交数据db.session.add(user)db.session.commit()return{code :0,msg :create success !}查询数据在Flask-SQLAlchemy 中执行数据查询的方式非常多示例Model.query.all()# 获取表内的所有数据Model.query.first()# 获取第一个查询结果Model.query.get(id)# 获取id 进行查询Model.query.filter().all()# 筛选查询相当于sql 中的where 语句Model.query.filter_by().all()# 筛选查询相当于sql 中的where 语句Model.query.filter().one_or_none()# 筛选查询相当于sql 中的wherelimit并且只获取一条数据修改和删除数据在Flask-SQLAlchemy 中无论是更新还是删除只要使用了db.session 进行操作都需要调用commit() 才会将数据同步到实际数据库中# 1 .通过调用updated 方法进行更新支持批量Students.query.filter_by(nameyy ).update({fullname :xx })# 2 .通过修改模型实例属性进行更新studentStudent.query.first()student.nameimoocdb.session.commit()# 1 .通过调用delete 方法删除数据支持批量Student.query.filter_by(nameimooc).delete()# 2 .通过db.session.delete 进行删除studentStudent.query.first()db.session.delete(student)db.session.commit()重写SQLAlchemy核心类实现自动提交commit与rollback对于新增、修改、删除的操作每次都需要写db.session.commit() 进行提交并且在业务逻辑中如果触发了异常还需要调用db.session.rollback() 进行回滚例如try:studentStudent.query.first()student.nameimoocdb.session.commit()exceptExceptionase:db.session.rollback()对于重复性的操作一般的方式是提供一个工具方法或工具类所以可以重写SQLAlchemy 核心类创建auto_commit并使用contextmanager 装饰该函数。fromcontextlibimportcontextmanagerfromflask_sqlalchemyimportSQLAlchemyas_SQLAlchemyclassSQLAlchemy(_SQLAlchemy):重写SQLAlchemy核心实现数据自动提交contextmanagerdefauto_commit(self):try:yieldself.session.commit()exceptExceptionase:self.session.rollback()raiseecontextmanager 装饰器的原理其实非常简单它将生成器函数中yield 之前的部分视为上下文的进入操作而yield 之后的部分视为离开操作。因此我们可以在yield 之前对数据进行操作新增、修改、删除在yield 之后执行self.session.commit() 提交更改。有了该方法后对于属于数据库操作我们可以这样简化一部分代码withdb.auto_commit():studentStudent.query.first()student.namexxxFlask-Migrate扩展介绍与使用我们使用db.create_all() 将ORM 模型映射到数据库的表中但是如果新增了ORM 模型或者更新了ORM 模型使用db.create_all() 都不会重新创建表或是更新表。需要先使用db.drop_all() 删除数据库中的所有表之后再调用db.create_all() 才能重新创建但是这样的话原来表中的数据就都被删除了这肯定是不行的于是就有了数据库迁移。Flask-Migrate 初始化在开发过程中随着需求的变化有可能需要添加或修改表的一些字段但是原表中的数据不能删除此时就需要创建新表并将旧表中的数据迁移至新表中Flask-Migrate 这个扩展就可以在不破坏数据的情况下更新数据库表的结构并完成数据从旧表到新表的迁移。安装命令pipinstallflask-migrate安装后进行初始化即可fromflask_migrateimportMigrate migrateMigrate()migrate.init_app(app,db,directoryinternal/migration)Flask-Migrate 常见命令初始化迁移环境在开始迁移数据之前需要先使用init 命令初始化创建一个迁移环境# 当flask 的应用入口在项目根目录且文件名为app.py并且实例变量名为app 时flask db init# 项目运行命令flask--appapp .server.app db init运行好命令后就会在directory 指定的位置创建一个迁移环境默认位置为./migrations。生成迁移脚本使用如下命令自动生成迁移脚本flask--appapp.server.app db migrate-mcreate_table 其中-m create_table 是可选的意思是为这个迁移写上一个简单的注释。在生成的迁移脚本中有两个函数upgrade()把迁移中的改动应用到数据库中downgrade()将改动撤销注意下在生产环境中一般不使用Flask-Migrate 迁移一般人工生成相应的SQL 执行迁移如果要使用迁移一定要仔细检查生成的迁移文件是否符合预期确认后才可以使用。更新及回滚数据库生成迁移脚本后可以使用upgrade 命令来更新数据库如下flask--appapp.server.app db upgrade每一次更新ORM 模型都需要执行migrate 命令生成迁移文件然后才可以使用upgrade 命令将更新同步到数据库中。如果想要回滚数据库可以使用downgrade 命令如下flask--appapp.server.app db downgrade每执行一次命令会向上回滚一个版本如果想一次性回滚到最原始的版本即删除所有数据库可以使用如下命令flask--appapp.server.app db downgrade base如果想回滚到特定的版本可以在downgrade 后带上特定的版本号如下flask--appapp.server.app db downgrade 版本号

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价