查找二阶关系:SQLAlchemy 抛出:“请使用 .select_from() 方法建立显式左侧”

Ama*_*shy 6 python sql sqlalchemy flask-sqlalchemy

我有一个User模型,一个Contact模型,还有一个Group模型。我希望在单个查询中找到给定特定用户User的所有二阶。也就是说,我想:Group

\n
    \n
  • 使用特定用户的所有联系人...
  • \n
  • ...获取同时也是给定用户联系人的所有用户,并将其用于...
  • \n
  • ...获取这些(二阶)用户的所有组
  • \n
\n

现在我得到了类似的信息(user.id我想要查找其联系人的特定用户在哪里):

\n
from sqlalchemy.orm import aliased\n\nSecondOrderUser = aliased(User)\n\n# This returns the phone number of all contacts who're a contact of the particular user\nsubquery = User.query \\\n    .join(Contact, Contact.user_id == User.id) \\\n    .filter(User.id == user.id) \\\n    .with_entities(Contact.contact_phone) \\\n    .subquery()\n\n# This filters all users by the phone numbers in the above query, gets their contacts, and gets the group\n# IDs of those contacts who are themselves users\ncontacts = User.query \\\n    .filter(User.phone.in_(subquery)) \\\n    .join(UserContact, UserContact.user_id == User.id) \\\n    .join(SecondOrderUser, SecondOrderUser.phone == UserContact.phone) \\\n    .join(Group, Group.user_id == SecondOrderUser.id) \\\n    .with_entities(Group.id) \\\n    .all()\n
Run Code Online (Sandbox Code Playgroud)\n

唯一共享的东西ContactUser将它们链接在一起\xe2\x80\x94,即查找本身就是用户的联系人)是一个通用电话号码。我[认为我]也可以用四个join语句和别名来做到这一点,但这给了我同样的错误。即:

\n
sqlalchemy.exc.InvalidRequestError: Can't determine which FROM clause to join from,\nthere are multiple FROMS which can join to this entity. Please use the .select_from()\nmethod to establish an explicit left side, as well as providing an explicit ON clause\nif not present already to help resolve the ambiguity.\n
Run Code Online (Sandbox Code Playgroud)\n

我在这里做错了什么?我很清楚在哪里/如何加入,这表明我完全错过了一些东西。

\n

Ama*_*shy 5

这里的问题有两个方面。每次使用表时(不仅仅是第二次以后),我们都必须为表添加别名,并且在使用时with_entities,我们必须使用在 \xe2\x80\x94 上进行比较的所有列,即使我们不打算这样做最后使用他们的数据。

\n

我的最终代码如下所示:

\n
from sqlalchemy.orm import aliased\n\nUser1 = aliased(User)\nUser2 = aliased(User)\nUser3 = aliased(User)\nContact1 = aliased(Contact)\nContact2 = aliased(Contact)\n\ncontacts = User1.query \\\n    .join(Contact1, Contact1.user_id == User1.id) \\\n    .join(User2, User2.phone == Contact1.phone) \\\n    .join(Contact2, Contact2.user_id == User2.id) \\\n    .join(User3, User3.phone == Contact2.phone) \\\n    .join(Group, Group.user_id == User3.id) \\\n    .with_entities(\n         Contact1.phone,\n         Contact1.user_id,\n         Contact2.phone,\n         Contact2.user_id,\n         Group.id\n         Group.user_id,\n         User1.id,\n         User2.id,\n         User2.phone,\n         User3.id,\n         User3.phone,\n     ) \\\n     .all()\n
Run Code Online (Sandbox Code Playgroud)\n