python-3.x - Peewee-async - 如何进行简单的 JOIN(或子查询/预取)
问题描述
我被困在一个peewee-async
关于 JOIN 的非常简单的问题上,或者我可能需要使用子查询或预取......我无法弄清楚我需要做什么样的查询。
我有 2 个数据库表(父/子):
class Group(PeeweeModel):
id = peewee.AutoField()
name = peewee.TextField()
class Channel(PeeweeModel):
id = peewee.AutoField()
name = peewee.TextField()
group = peewee.ForeignKeyField(Group, backref="channels")
我需要获取 1 个组对象,并且该对象有多个通道对象。
我试过了:
q = Group.select(Group, Channel).join(Channel)
但我backref
的“频道”始终是一个ModelQuery
实例,而不是实际的结果集。
完整代码
import asyncio
import peewee
import peewee_async
from peewee_async import Manager, PooledPostgresqlDatabase
database = PooledPostgresqlDatabase('test', max_connections=4, user='postgres', password='', host='127.0.0.1')
objects = peewee_async.Manager(database)
class PeeweeModel(peewee.Model):
class Meta:
database = database
class Group(PeeweeModel):
id = peewee.AutoField()
name = peewee.TextField()
class Channel(PeeweeModel):
id = peewee.AutoField()
name = peewee.TextField()
group = peewee.ForeignKeyField(Group, backref="channels")
Group.create_table()
Channel.create_table()
database.set_allow_sync(False)
async def handler():
# create 1 group object
group = await objects.create(Group, name="TestGroup")
# create 2 channel objects, assign to group
await objects.create(Channel, name="TestName1", group=group)
await objects.create(Channel, name="TestName2", group=group)
# Query 1 group, and hopefully it will have the channels
q = Group.select(Group, Channel).join(Channel)
results = await objects.execute(q)
for result in results:
print(result.channels) # problem: Channels is not a list of channel objects, but a `ModelSelect` instead
with objects.allow_sync():
Channel.drop_table(True)
Group.drop_table(True)
loop = asyncio.get_event_loop()
loop.run_until_complete(handler())
loop.close()
解决方案
我能够从专家那里获得帮助™,解决方案是使用prefetch()
:
async def handler():
# create 1 group object
group = await objects.create(Group, name="TestGroup")
# create 2 channel objects, assign to group
await objects.create(Channel, name="TestName", group=group)
await objects.create(Channel, name="TestName", group=group)
# Query 1 group, and hopefully it will have the channels
q = Group.select(Group)
groups = await objects.prefetch(q, Channel.select(Channel))
for group in groups:
print(group, group.channels) # channels is a list of channels.
with objects.allow_sync():
Channel.drop_table(True)
Group.drop_table(True)
Peewee 会自己找出关系(backref)。
推荐阅读
- c# - 来自源“http://localhost:”的 localhost:/token 请求已被 CORS 阻止
- google-maps - 当我在谷歌地图上标记时如何获取地址的所有详细信息。然后它将在颤动中填充文本框
- android - 如何在mp图表的条形图中显示其他条形图的顶部
- android - 为什么小米设备未激活请勿打扰?
- java - Eclipse 找不到或无法加载主类
- ios - Meatl 中的剪耳跟踪算法
- css - 为不同的类声明变量
- python - 暴露 Python 程序的端点
- python - 如何以最好的方式附加从维基百科抓取的python代码
- android - Android TextView 不需要的填充问题