ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

peewee ORM 实战指南:从模型定义到复合查询的完整入门

peewee ORM 实战指南:从模型定义到复合查询的完整入门 peewee ORM 实战指南从模型定义到复合查询的完整入门【免费下载链接】peeweea small, expressive orm -- supports postgresql, mysql, sqlite, now with asyncio项目地址: https://gitcode.com/gh_mirrors/pe/peeweePeewee 是一个简单而小巧的 Python ORM对象关系映射库核心代码集中在一个文件 peewee.py 中概念少而表达力强容易学习且使用直观。本文以仓库根目录 README.rst 为骨架结合项目源码、文档与示例应用带你从零掌握 Peewee 的模型定义、数据写入、查询组合、关联 JOIN、聚合分页与原子更新并了解其扩展生态与实战案例。Peewee 是什么按照 README 的定位Peewee 是 a small, expressive ORM核心特性包括概念极少、表达力强易于学习且使用直觉化支持 Python 2.7 与 3.4当前仓库 peewee.py 中版本号为3.17.8原生支持SQLite、MySQL、MariaDB、PostgreSQL四类数据库拥有数量庞大的扩展库Playhouse覆盖全文检索、连接池、迁移、逆向工程等能力。Peewee 的模型风格与 Django 相似模型类对应数据库表、字段实例对应表的列、模型实例对应表中的行三者映射关系清晰直接。同时Peewee 提供了声明式模型定义、链式查询构建器、SQL 函数fn支持以及 Django 风格的Meta配置类。说明README 中提到的 Python 2.7 为历史兼容范围。当前仓库源码基于现代 Python 特性开发并提供了基于 Cython 的可选 C 扩展加速见 setup.py建议在较新的 Python 3 环境中使用。安装与依赖Peewee 通过标准setup.py发布。安装时可选编译 C 扩展playhouse._sqlite_udf、playhouse._sqlite_ext如果安装了 Cython 会从.pyx生成扩展模块否则回退到预生成的 C 文件前提是运行在 CPython 上见 setup.py。数据库驱动方面peewee.py 会按优先级自动探测可用驱动SQLite 优先使用pysqlite3/pysqlite2否则回退标准库sqlite3PostgreSQL 支持psycopg2含psycopg2cffi兼容层与新版psycopg3MySQL 优先PyMySQL回退MySQLdb。因此你只需为所用数据库安装对应驱动即可无需额外配置。学习路线图README 为新用户规划了一条循序渐进的学习路径对应的仓库文档如下主题仓库文档快速上手docs/peewee/quickstart.rst完整示例Twitter 风格 Web 应用docs/peewee/example.rst、examples/twitter/app.py交互式使用docs/peewee/interactive.rst模型与字段docs/peewee/models.rst查询docs/peewee/querying.rst关系与连接docs/peewee/relationships.rst数据库配置docs/peewee/database.rst查询操作符docs/peewee/query_operators.rstREADME 强烈建议打开一个交互式 Python Shell 边敲边学这样能直观感受查询表达式的构建过程。定义模型以 README 中的 User/Tweet 模型为例定义模型与 Django、SQLAlchemy 类似from peewee import * import datetime db SqliteDatabase(my_database.db) class BaseModel(Model): class Meta: database db class User(BaseModel): username CharField(uniqueTrue) class Tweet(BaseModel): user ForeignKeyField(User, backreftweets) message TextField() created_date DateTimeField(defaultdatetime.datetime.now) is_published BooleanField(defaultTrue)关键点解读数据库实例SqliteDatabase(my_database.db)管理 SQLite 连接也可以替换为MySQLDatabase、MariaDBDatabase、PostgresqlDatabase等分别对应 peewee.py 中的MySQLDatabase、PostgresqlDatabase类。BaseModel 约定把database放在基类的Meta中后续所有模型继承它即可复用数据库配置避免重复声明这是官方推荐做法见 docs/peewee/models.rst。字段与默认值created_date、is_published都带default写入时未显式赋值会自动使用默认值。外键与反向引用ForeignKeyField(User, backreftweets)让User实例可以通过user.tweets访问其所有推文。主键未显式指定primary_key时Peewee 会自动添加名为id的自增整数主键AutoField。连接数据库并建表db.connect() db.create_tables([User, Tweet])db.connect()显式打开连接是良好实践能立刻暴露数据库连接错误而不是等到第一条查询执行时才报错。create_tables()会为模型创建包含正确列、索引、序列sequence和外键约束的表。写入数据create 与 savecharlie User.create(usernamecharlie) huey User(usernamehuey) huey.save() # created_date / is_published 未赋值将使用字段默认值 Tweet.create(usercharlie, messageMy first tweet)User.create(...)直接插入一行并返回模型实例User(usernamehuey)先构造实例再调用save()持久化save()返回受影响行数Tweet.create(usercharlie, ...)中外键可以直接传模型实例也可传对应主键值见 docs/peewee/querying.rst字段默认值defaultdatetime.datetime.now、defaultTrue在插入时自动生效。底层上Model.create会构建一个InsertQuery并执行同时自动回填主键到实例参见 peewee.py 中Model.create与InsertQuery的实现。查询从单条到复合条件单条记录User.get(User.username charlie)Model.get是User.select().where(...).get()的简写形式返回满足条件的单条记录无匹配时抛出DoesNotExist。列表查询与 IN 子查询usernames [charlie, huey, mickey] users User.select().where(User.username.in_(usernames)) tweets Tweet.select().where(Tweet.user.in_(users))第二条查询展示了子查询能力Tweet.user.in_(users)中传入的是一个查询对象Peewee 会将其编译为IN (SELECT ...)形式。查询构建器支持任意嵌套这正是 Peewee 表达力强的体现。等价的 JOIN 写法tweets (Tweet .select() .join(User) .where(User.username.in_(usernames)))以上两种写法结果等价前者使用子查询后者使用INNER JOIN。JOIN常量定义在 peewee.pyLEFT_OUTERLEFT OUTER JOIN支持INNER、LEFT_OUTER、RIGHT_OUTER、FULL、CROSS等连接类型。组合条件与日期过滤tweets_today (Tweet .select() .where( (Tweet.created_date datetime.date.today()) (Tweet.is_published True)) .count())、|、~分别对应 SQL 的 AND、OR、NOT多个条件可以任意括号嵌套count()直接生成SELECT COUNT(*)聚合查询返回整数。排序User.select().order_by(User.username).paginate(3, 20)order_by支持.asc()/.desc()也可.desc(nulls...)控制 NULL 排序paginate(page, paginate_by)按页取数默认每页 20 条上述代码返回第 3 页第 41–60 条。paginate方法定义于 peewee.py本质是limit(paginate_by).offset((page - 1) * paginate_by)。聚合与分组统计每个用户的推文数tweet_ct fn.Count(Tweet.id) users (User .select(User, tweet_ct.alias(ct)) .join(Tweet, JOIN.LEFT_OUTER) .group_by(User) .order_by(tweet_ct.desc()))要点fn是 Peewee 提供的 SQL 函数入口定义于 peewee.pyfn Function(None, None)可调用任意 SQL 函数如fn.Count、fn.Lower、fn.Substrtweet_ct.alias(ct)编译为COUNT(tweet.id) AS ct查询结果中ct会作为属性挂到返回的User实例上使用JOIN.LEFT_OUTER保证没有推文的用户计数为 0也不会被过滤掉group_by(User)按用户分组order_by(tweet_ct.desc())按计数倒序排列。类似地fn.Lower(fn.Substr(Person.name, 1, 1)) g这类嵌套函数表达式可直接用于where过滤见 docs/peewee/quickstart.rst 的 SQL Functions 一节。原子更新避免竞态条件Counter.update(countCounter.count 1).where(Counter.url request.url)README 特别强调对于读取后再写入的计数类操作绝不能在两步中完成存在竞态条件而应使用单条原子 UPDATE 表达式。Counter.count 1会被编译为 SQL 侧的count count 1在数据库层面原子执行天然规避并发问题。源码级印证核心机制一览能力实现位置说明版本号peewee.py__version__ 3.17.8JOIN 常量peewee.pyLEFT_OUTERLEFT OUTER JOIN等SQL 函数入口peewee.pyfn Function(None, None)分页peewee.pySelect.paginate(page, paginate_by20)事务/原子操作peewee.pyDatabase.atomic()上下文管理器驱动探测peewee.pySQLite/psycopg2/psycopg3/PyMySQL 自动选择C 扩展构建setup.pyCython 可选加速atomic()支持嵌套事务与保存点savepoint是批量写入、保证一致性的常用手段。例如将insert_many包进with db.atomic():可以显著提升批量插入速度并保证要么全部成功、要么全部回滚。扩展生态playhousePeewee 的扩展以playhouse命名空间组织详见 playhouse/README.md覆盖三大类数据库厂商扩展SQLite 扩展FTS3/4/5 全文检索、BM25 排序算法、虚拟表、闭包表、JSON、LSM 键值存储、BLOB 与在线备份 API见 playhouse/sqlite_ext.py、APSW 驱动playhouse/apsw_ext.py、SQLCipher 加密库playhouse/sqlcipher_ext.py、SqliteQ 专用写线程playhouse/sqliteq.py、PostgreSQL 扩展JSON/JSONB、HStore、数组、服务端游标、全文检索见 playhouse/postgres_ext.py与 MySQL 扩展playhouse/mysql_ext.py高层工具库Compressed/Pickle 字段playhouse/fields.py、模型与字典互转playhouse/shortcuts.py、Hybrid 属性playhouse/hybrid.py、信号机制 pre/post-save、delete、initplayhouse/signals.py、类 dataset 的高层 APIplayhouse/dataset.py、键值存储playhouse/kv.py数据库管理与框架集成pwiz 逆向生成模型pwiz.py、Schema 迁移playhouse/migrate.py、连接池playhouse/pool.py、跨库反射playhouse/reflection.py、数据库 URLplayhouse/db_url.py、测试工具playhouse/test_utils.py与 Flask 集成playhouse/flask_utils.py。真实项目示例仓库examples/目录下提供了多个可直接运行的完整应用examples/twitter/app.pyREADME 中推荐的 Twitter 风格 Web 应用演示了BaseModel模式、自引用外键用户关注关系、CharField(uniqueTrue)用户名字段以及该用户关注了谁 / 谁关注了该用户这类多表 JOIN 查询examples/blog/app.py基于 Flask Peewee 的博客应用使用playhouse.flask_utils.FlaskDB管理请求级数据库连接sqliteext:///数据库 URL 接入 SQLite 扩展并展示了BooleanField(indexTrue)、DateTimeField(defaultdatetime.datetime.now, indexTrue)等带索引字段的建模方式其他单文件示例如 examples/diary.py加密命令行日记、examples/adjacency_list.py邻接表树、examples/graph.py图算法、examples/anomaly_detection.py异常检测等展示了 Peewee 在不同场景下的灵活性。对接现有数据库pwiz如果已有现成数据库可用 pwiz 自动生成模型代码python -m pwiz -e postgresql charles_blog blog_models.py-e指定数据库引擎如sqlite、mysql、postgresqlpwiz 会通过反射playhouse/reflection.py读取表结构、字段类型、外键与索引输出可直接使用的模型定义。对应的集成测试见 tests/pwiz_integration.py。社区与进一步学习完整文档与更多示例见仓库 docs 目录从 docs/index.rst 开始浏览查询进阶聚合、CTE、窗口函数、复合查询等大量实例位于 docs/peewee/querying.rst 与 docs/peewee/query_examples.rst测试体系仓库自带覆盖完善的测试集tests可运行 runtests.py 执行tests/base.py提供了针对 SQLite/MySQL/PostgreSQL 的统一测试基类性能对比仓库提供了 bench.py 基准脚本可用于对比 select/insert/bulk 等常见操作耗时。结语从 README 的一个 Tweet 示例出发本文完整走通了 Peewee 的建模、建表、写入、查询、JOIN、聚合、分页与原子更新全流程并用仓库源码、扩展清单与真实示例做了印证。Peewee 的核心设计哲学是概念少而精——掌握本文的模型与查询模式你就能覆盖绝大多数日常数据库操作需要更高级能力时playhouse扩展与完整文档随时可以继续深入。【免费下载链接】peeweea small, expressive orm -- supports postgresql, mysql, sqlite, now with asyncio项目地址: https://gitcode.com/gh_mirrors/pe/peewee创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表