Peewee ORM 查询构建器深度解析

Peewee ORM 查询构建器深度解析

peewee coleifer/peewee: 是一个用 Python 实现的小巧的 ORM 库,可以方便地在 Python 应用中实现数据库操作。适合对 Python、ORM 库和想要实现 Python 数据库操作的开发者。 peewee 项目地址: https://gitcode.com/gh_mirrors/pe/peewee

概述

Peewee 是一个轻量级但功能强大的 Python ORM 框架,其核心查询构建器提供了灵活且直观的方式来构建和执行 SQL 查询。本文将深入探讨 Peewee 的查询构建器功能,帮助开发者更好地理解和使用这一强大工具。

表结构定义

在 Peewee 中,我们可以通过两种方式定义表结构:

# 显式声明列
Person = Table('person', ('id', 'first', 'last'))

# 不声明列,通过.c属性动态访问
Reminder = Table('reminder')

最佳实践:建议显式声明列,这样可以获得更好的代码提示和类型检查支持。

数据库绑定

在实际应用中,我们需要将表绑定到数据库连接:

db = SqliteDatabase('my_app.db')
Person = Person.bind(db)

绑定后,执行查询时就不需要每次都传递数据库连接对象了。

查询基础

简单查询

# 查询前3条笔记并按时间排序
query = Note.select().order_by(Note.timestamp).limit(3)
for note_dict in query:
    print(note_dict['content'])

注意:默认返回字典格式的结果,也可以通过.tuples().namedtuples().objects()方法指定不同的结果容器。

带条件的查询

# 查询2018年以后的笔记及其作者信息
query = (Note
         .select(Note.content, Note.timestamp, Person.first, Person.last)
         .join(Person, on=(Note.person_id == Person.id))
         .where(Note.timestamp >= datetime.date(2018, 1, 1))
         .order_by(Note.timestamp)
         .namedtuples())

聚合查询

# 查询笔记数量最多的用户
name = Person.first.concat(' ').concat(Person.last)
query = (Person
         .select(name.alias('name'), fn.COUNT(Note.id).alias('count'))
         .join(Note, JOIN.LEFT_OUTER, on=(Note.person_id == Person.id))
         .group_by(name)
         .order_by(fn.COUNT(Note.id).desc()))

关键点

  • 使用fn对象调用SQL函数
  • .alias()方法用于指定列别名
  • 可以将表达式存储在变量中复用

高级查询技巧

表别名与子查询

# 查询每个人最新发布的笔记
NA = Note.alias('na')
max_note = (NA
            .select(NA.person_id, fn.MAX(NA.timestamp).alias('max_ts'))
            .group_by(NA.person_id)
            .alias('max_note'))

query = (Note
         .select(Note.content, Note.timestamp, Person.first, Person.last)
         .join(max_note, on=((max_note.c.person_id == Note.person_id) &
                            (max_note.c.max_ts == Note.timestamp)))
         .join(Person, on=(Note.person_id == Person.id)))

动态列访问

对于未显式声明列的表,可以使用.c属性访问列:

query = (Reminder
         .select(Reminder.c.alarm, Note.content)
         .join(Note, on=(Reminder.c.note_id == Note.id))

数据操作

插入数据

# 单条插入
zaizee_id = Person.insert(first='zaizee', last='cat').execute()

# 批量插入
people = [
    {'first': 'Bob', 'last': 'Foo'},
    {'first': 'Herb', 'last': 'Bar'}]
Person.insert(people).execute()

更新数据

# 简单更新
Person.update(last='Baze').where(Person.first == 'Bob').execute()

# 原子更新
PageView.update({PageView.count: PageView.count + 1})
    .where(PageView.url == some_url)
    .execute()

删除数据

# 直接删除
Note.delete().where(Note.timestamp < datetime.date(2018, 1, 1)).execute()

# 使用子查询删除
foo_people = Person.select(Person.id).where(Person.last == 'Foo')
Note.delete().where(Note.person_id.in_(foo_people)).execute()

复杂查询示例

递归CTE查询

# 计算斐波那契数列前10项
base = Select(columns=(
    Value(1).alias('n'),
    Value(0).alias('fib_n'),
    Value(1).alias('next_fib_n'))).cte('fibonacci', recursive=True)

n = (base.c.n + 1).alias('n')
recursive_term = Select(columns=(
    n,
    base.c.next_fib_n,
    base.c.fib_n + base.c.next_fib_n)).from_(base).where(n < 10)

fibonacci = base.union_all(recursive_term)
query = fibonacci.select_from(fibonacci.c.n, fibonacci.c.fib_n)

总结

Peewee 的查询构建器提供了强大而灵活的方式来构建各种复杂SQL查询。通过本文的介绍,你应该已经掌握了:

  1. 基本的表定义和查询构建
  2. 高级查询技巧如子查询、表别名和递归CTE
  3. 数据操作的基本方法
  4. 复杂查询的构建思路

Peewee 的查询构建器设计既保持了SQL的灵活性,又提供了Pythonic的优雅语法,是构建数据库应用的强大工具。

peewee coleifer/peewee: 是一个用 Python 实现的小巧的 ORM 库,可以方便地在 Python 应用中实现数据库操作。适合对 Python、ORM 库和想要实现 Python 数据库操作的开发者。 peewee 项目地址: https://gitcode.com/gh_mirrors/pe/peewee

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

郦嵘贵Just

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值