【问题标题】:SQLAlchemy query using list of elements使用元素列表的 SQLAlchemy 查询
【发布时间】:2017-06-08 13:01:52
【问题描述】:

我建立了一个 SQLAlchemy 数据库,大致如下:

class ChangelogEntry(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    apps = db.relationship('App', secondary=app_changelogEntry)
    appGroups = db.relationship('AppGroup', secondary=appGroup_changelogEntry)

class App(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(32), unique=True, index=True)
    appGroups = db.relationship('AppGroup', secondary=app_appGroup)

class AppGroup(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(32), unique=True, index=True)
    apps = db.relationship('App', secondary=app_appGroup)

更新:

app_changelogEntry = db.Table('App_ChangelogEntry',
    db.Column('app_id', db.Integer, db.ForeignKey('app.id')),
    db.Column('changelog_id', db.Integer, db.ForeignKey('changelog_entry.id'))
)

appGroup_changelogEntry = db.Table('AppGroup_ChangelogEntry',
    db.Column('appGroup_id', db.Integer, db.ForeignKey('app_group.id')),
    db.Column('changelogEntry_id', db.Integer, db.ForeignKey('changelog_entry.id'))
)

app_appGroup = db.Table('App_AppGroup',
    db.Column('app_id', db.Integer, db.ForeignKey('app.id')),
    db.Column('appGroup_id', db.Integer, db.ForeignKey('app_group.id'))
)

一个 App 可以是多个 AppGroups 的一部分,用户可以创建 ChangelogEntries 并且可以选择此 ChangelogEntry 所属的 App/Apps 和/或 AppGroups。

看起来像这样:

好的。我只想获取属于例如的所有 ChangelogEntries App3(App3 是 AppGroups Group1 和 Group2 的一部分),在本例中是 Group1 和 Group2。

希望你能帮我解决这个问题!

【问题讨论】:

  • 请同时包含关联表。
  • 我是否理解正确,因为您希望查询与给定应用程序有直接关系的变更日志条目,以及与包含给定应用程序/应用程序的组有关系的变更日志条目?
  • 我现在包含了关联表。我希望现在更容易理解。但你是对的,这就是我想要的..

标签: python sql sqlalchemy flask-sqlalchemy


【解决方案1】:

联合可能非常适合手头的任务:找到具有直接应用关系和通过组的变更日志条目的联合。使用内连接:

direct = db.session.query(ChangelogEntry).\
    join("apps").\
    filter(App.name == "App3")

groups = db.session.query(ChangelogEntry).\
    join("appGroups", "apps").\
    filter(App.name == "App3")

direct.union(groups).all()

由于组加入的多对多关系可能会为更改日志条目生成多行,但使用 UNION 而不是 UNION ALL 可以解决这个问题。为了避免重复行开始,您可以使用 semijoins/EXISTS:

direct = db.session.query(ChangelogEntry).\
    filter(ChangelogEntry.apps.any(App.name == "App3"))

groups = db.session.query(ChangelogEntry).\
    filter(ChangelogEntry.appGroups.any(
        AppGroup.apps.any(App.name == "App3")))

direct.union(groups).all()

【讨论】:

  • 谢谢。我是 sql 和 sqlalchemy 的新手。您能否告诉我 join("apps")/join("appGroups", "apps") 的作用。 (我现在已经加入了)
  • 查看Query.join() 文档。简而言之,在单个实体查询中,您可以将用作连接的 on 子句的关系作为字符串传递。您还可以生成连接链,例如join("appGroups", "apps"),相当于join(ChangelogEntry.appGroups).join(AppGroup.apps)。当您将多对多关系作为 on 子句传递时,SQLAlchemy 会在幕后为您处理形成所需的关联表连接。
猜你喜欢
  • 2016-12-01
  • 1970-01-01
  • 2020-09-19
  • 1970-01-01
  • 2016-05-07
  • 2018-01-14
  • 2021-12-19
  • 2020-03-10
  • 2016-12-22
相关资源
最近更新 更多