简体   繁体   English

sqlalchemy将两个表连接在一起

[英]sqlalchemy join two tables together

I am wanting to map a class object to a table that is a join between two tables, and all the columns from one table and only one column from the joined table being selected (mapped). 我想将一个类对象映射到一个表,该表是两个表之间的联接,并且一个表中的所有列以及联接表中的仅一列被选中(映射)。

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

Am I doing this right? 我这样做对吗?

If all you want to do is pull in one extra column from a JOIN, I'd not muck about with an arbitrary select mapping. 如果您要做的只是从JOIN中拉出另外一列,那么我不会为任意选择映射而烦恼。 As the documentation points out : 正如文档所指出的

The practice of mapping to arbitrary SELECT statements, especially complex ones as above, is almost never needed; 几乎不需要映射到任意SELECT语句的实践,尤其是如上所述的复杂语句。 it necessarily tends to produce complex queries which are often less efficient than that which would be produced by direct query construction. 它必然会产生复杂的查询,而这些查询的效率通常比直接查询构造要低。 The practice is to some degree based on the very early history of SQLAlchemy where the mapper() construct was meant to represent the primary querying interface; 这种做法在某种程度上基于SQLAlchemy的早期历史,在该历史中, mapper()构造旨在表示主要的查询接口。 in modern usage, the Query object can be used to construct virtually any SELECT statement, including complex composites, and should be favored over the “map-to-selectable” approach. 在现代用法中, Query对象实际上可以用于构造任何SELECT语句,包括复杂的组合,并且应优先于“映射到可选”方法。

You'd just either select that extra column in your application: 您只需在应用程序中选择该额外的列:

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

or you can register a relationship on the Table1Model and an association property that always pulls in the extra column: 或者,您可以在Table1Model上注册一个关系,并在一个总是拉入额外列的关联属性上注册:

class Table1Model(Base):
    # ...

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

The association property manages the Table2Model.description column of the joined row as you interact with it on Table1Model instances. Table1Model实例上Table1Model交互时,关联属性将管理联接行的Table2Model.description列。

That said, if you must stick with a join() query as the base, then you could just exclude the extra, duplicated columns from the join, with a exclude_properties mapper argument : 就是说,如果您必须坚持使用join()查询作为基础,则可以使用exclude_properties mapper参数exclude_properties 排除多余的重复列:

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

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

The new model then uses all the columns from the join to create attributes with the same names, except for those listed in `exclude_properties. 然后,新模型将使用联接中的所有列来创建具有相同名称的属性,但“ exclude_properties”中列出的属性除外。

Or you can keep using duplicated column names in the model simply by giving them a new name: 或者,您可以简单地通过给它们提供新的名称来继续在模型中使用重复的列名称:

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

class JoinedTableModel(Base):
    __table__ = join_table

    table1_description = table1.c.description

You can rename any column from the join this way, at which point they will no longer conflict with other columns with the same base name from the other table. 您可以通过这种方式重命名连接中的任何列,此时它们将不再与其他表中具有相同基本名称的其他列冲突。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM