Peewee select 循环依赖

Peewee select with circular dependency

我有两个模型 RoomUser。每个用户都被分配到一个房间,其中一个是所有者。

DeferredUser = DeferredRelation()

class Room(Model):
    owner = ForeignKeyField(DeferredUser)

class User(Model):
    sessid = CharField()
    room = ForeignKeyField(Room, related_name='users')

DeferredUser.set_model(User)

现在,有了 sessid 的所有者,我想 select 他的房间和所有分配的用户。但是当我这样做时:

(Room.select(Room, User)
     .join(User, on=Room.owner)
     .where(User.sessid==sessid)
     .switch(Room)
     .join(User, on=User.room))

计算结果为:

SELECT "t1".*, "t2".* # skipped column names
FROM "room" AS t1
INNER JOIN "user" AS t2 ON ("t1"."owner_id" = "t2"."id")
INNER JOIN "user" AS t2 ON ("t1"."id" = "t2"."room_id")
WHERE ("t2"."sessid" = ?) [<sessid>]

并抛出 peewee.OperationalError: ambiguous column name: t2.id 因为 t2 被定义了两次。
我实际需要做的是:

room = (Room.select(Room)
            .join(User.sessid=sessid)
            .get())
users = room.users.execute()

但这是 N+1 查询,我想在单个查询中解决它,例如:

SELECT t1.*, t3.* FROM room AS t1
INNER JOIN user AS t2 ON t1.owner_id = t2.id
INNER JOIN user as t3 ON t3.room_id = t1.id
WHERE t2.sessid = ?;

是否有执行此操作的 peewee 方法,或者我需要手动输入此 SQL 查询?

当您在两个不同的上下文中使用相同的 table 时,您需要使用模型别名。所以:

Owner = User.alias()  # Create a model alias.

(Room.select(Room, Owner, User)
 .join(Owner, on=(Room.owner == Owner.id))
 .where(Owner.sessid == sessid)
 .switch(Room)
 .join(User, on=User.room))

http://docs.peewee-orm.com/en/latest/peewee/api.html?#Model.alias