【问题标题】:SQLAlchemy ORM Inserting Related Objects without Selecting ThemSQLAlchemy ORM插入相关对象而不选择它们
【发布时间】:2011-01-11 22:31:10
【问题描述】:

SQLAlchemy ORM tutorial中,大致描述了创建对象关系的过程如下。假设我有一个表 Articles、一个表 Keywords 和一个创建多对多关系的表 Articles_Keywords。

article = meta.Session.query(Article).filter(id=1).one()
keyword1 = meta.Session.query(Keyword).filter(id=1).one()
keyword2 = meta.Session.query(Keyword).filter(id=2).one()
article.keywords = [keyword1,keyword2]
meta.Session.commit()

我已经有了相关关键字的主键 ID 号,所以我需要做的就是将这些 ID 添加到链接到本文的 Articles_Keywords 表中。问题是,为了使用 ORM 做到这一点,我必须从数据库中选择所有关键字,这似乎无缘无故地增加了很多开销。

有没有办法在不运行任何 SQL 来选择关键字的情况下创建这种关系?

【问题讨论】:

    标签: python performance orm sqlalchemy


    【解决方案1】:

    不幸的是,ORM 无法在不查询数据库的情况下保持对象状态的健全。但是,您可以轻松绕过 ORM 并插入关联表。假设 Articles_Keywords 是 Table 对象:

     meta.Session.execute(Articles_Keywords.delete(Articles_Keywords.c.article_id == 1))
     meta.Session.execute(Articles_Keywords.insert(), [
         {'article_id': 1, 'keyword_id': 1},
         {'article_id': 1, 'keyword_id': 2},
     ])
    

    如果您绕过 ORM,则不会更新已加载的集合以反映数据库中的更改。如果你需要刷新集合调用 Session.expire 就可以了。这将导致集合在下次访问时重新加载。

    meta.Session.expire(article, ['keywords'])
    

    【讨论】:

      【解决方案2】:

      Ants 有正确的答案,但如果您将 article_keywords 显式映射为关联对象,您只需创建新的 ArticleKeyword 对象并直接添加它们。

      【讨论】:

      • 五年后有没有办法通过 ORM 做到这一点?现在就绕过去。
      • 这个答案通过ORM。映射辅助表,使用您想要的两个 id 创建一个。
      猜你喜欢
      • 1970-01-01
      • 2021-05-16
      • 2010-12-06
      • 2020-05-16
      • 1970-01-01
      • 2020-02-14
      • 1970-01-01
      • 2013-05-19
      • 2019-04-25
      相关资源
      最近更新 更多