【问题标题】:sqlalchemy join two tables togethersqlalchemy 将两个表连接在一起
【发布时间】:2019-03-13 00:08:09
【问题描述】:

我想将一个类对象映射到一个表,该表是两个表之间的连接,并且一个表中的所有列和连接表中的一列被选中(映射)。

join_table = join(table1, table2, tabl1.c.description==table2.c.description)
model_table_join= select([table1, table2.c.description]).select_from(join_table).alias()

我这样做对吗?

【问题讨论】:

  • 您的意思是您正在实施Mapping a Class against Multiple Tables?那你就不用创建model_table_join了,join_table对象就够了。
  • @Martijn Pieters 我的问题是两个表都有一些名称相同的字段,我只想包含 table2 中的一列。
  • 如果我这样做:join(table1, table2.c.description, table1.c.number==table2.c.number) 我收到 FROM 表达式预期错误。
  • 联接需要两个表,而不是一列。 select_from 方法可能是正确的方向,但我不能让复合键工作。老实说,我会完全避免这种情况,只添加一个关系和一个代理列的混合属性。
  • 我该怎么做呢?

标签: python join sqlalchemy


【解决方案1】:

如果您只想从 JOIN 中拉入一个额外的列,我不会对任意选择映射感到困惑。作为documentation points out

映射到任意SELECT 语句的做法,尤其是上述复杂的语句,几乎不需要;它必然倾向于产生复杂的查询,这些查询的效率通常低于直接查询构造所产生的效率。这种做法在某种程度上基于 SQLAlchemy 的早期历史,其中 mapper() 构造旨在表示主要查询接口;在现代用法中,Query 对象可用于构造几乎任何 SELECT 语句,包括复杂的复合,并且应该优于“映射到可选”方法。

您只需在应用程序中选择额外的列:

session.query(Table1Model, Table2Model.description).join(Table2Model)

或者您可以在Table1Modelassociation property 上注册一个始终拉入额外列的关系:

class Table1Model(Base):
    # ...

    _table2 = relationship('Table2Model', lazy='join')
    description = association_proxy('_table2', 'description')

关联属性在您与 Table1Model 实例交互时管理连接行的 Table2Model.description 列。

也就是说,如果您必须坚持使用 join() 查询作为基础,那么您可以使用 exclude_properties mapper argument 从连接中排除额外的重复列:

join_table = join(table1, table2, table1.c.description == table2.c.description)

class JoinedTableModel(Base):
    __table__ = join_table
    __mapper_args__ = {
        'exclude_properties' : [table1.c.description]
    }

然后,新模型使用连接中的所有列来创建具有相同名称的属性,`exclude_properties 中列出的属性除外。

或者您可以在模型中继续使用重复的列名,只需给它们一个新名称:

join_table = join(table1, table2, table1.c.description == table2.c.description)

class JoinedTableModel(Base):
    __table__ = join_table

    table1_description = table1.c.description

您可以通过这种方式重命名连接中的任何列,此时它们将不再与其他表中具有相同基本名称的其他列发生冲突。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-26
    • 2021-03-08
    • 1970-01-01
    相关资源
    最近更新 更多