我想将一个类对象映射到一个表,该表是两个表之间的联接,并且一个表中的所有列以及联接表中的仅一列被选中(映射)。
join_table = join(table1, table2, tabl1.c.description==table2.c.description)
model_table_join= select([table1, table2.c.description]).select_from(join_table).alias()
我这样做正确吗?
答案 0 :(得分:1)
如果您要做的只是从JOIN中拉出一列,那么我不会为任意选择映射而烦恼。作为documentation points out:
几乎不需要映射到任意
SELECT
语句的实践,尤其是如上所述的复杂语句。它必然会产生复杂的查询,而这些查询的效率通常比直接查询构造要低。这种做法在某种程度上基于SQLAlchemy的早期历史,其中mapper()
构造旨在表示主要的查询接口。在现代用法中,Query
对象实际上可用于构造任何SELECT
语句,包括复杂的复合内容,并且应优先于“映射到可选”方法。
您只需在应用程序中选择该额外的列:
session.query(Table1Model, Table2Model.description).join(Table2Model)
或者您可以在Table1Model
和association property上注册一个关系,该关系始终会拉出额外的列:
class Table1Model(Base):
# ...
_table2 = relationship('Table2Model', lazy='join')
description = association_proxy('_table2', 'description')
当您在Table2Model.description
实例上与之交互时,关联属性将管理联接行的Table1Model
列。
也就是说,如果您必须坚持使用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
您可以通过这种方式重命名连接中的任何列,此时它们将不再与其他表中具有相同基本名称的其他列冲突。