SQLAlchemy二级关系不使用JOIN

时间:2019-08-19 11:32:49

标签: python mysql sqlalchemy

我在SQLAlchemy上创建了多对多关系,但是由于某种原因,当我访问它时,它不会发出JOIN子句,而是从三个表的叉积中进行选择,并使用WHERE子句进行过滤。我不明白为什么要这么做,以及如何解决。

这是关联表和主要模型的python代码。辅助模型过于复杂,我认为它具有skuaccount_id列的事实,这些列具有索引(并且一起是PK的一部分)足以继续进行

product_info_to_product_profile_association_table = Table(
    "tpl_products_to_product_profiles_r1",
    metadata,
    sa.Column(
        "sku",
        sa.String(128),
# This FK is failing at the MySQL level
        # sa.ForeignKey(ProductInfo.sku),
        nullable=False,
    ),
    sa.Column(
        "account_id", mysql.INTEGER(11), sa.ForeignKey(ProductInfo.account_id), nullable=False
    ),
    sa.Column(
        "product_profile_id",
        mysql.INTEGER(11, unsigned=True),
        sa.ForeignKey("tpl_product_profiles.id"),
        nullable=False,
    ),
    sa.UniqueConstraint("sku", "account_id", "product_profile_id", name="product_unique"),
)
​
​
class ProductProfile(BillingBaseModel):
​
    __tablename__ = "tpl_product_profiles"
​
    id = sa.Column(mysql.INTEGER(11, unsigned=True), primary_key=True)
    name = sa.Column(sa.String(90), nullable=False)
    account_id = sa.Column(mysql.INTEGER(11), sa.ForeignKey(Account.id), nullable=False)
​
    product_infos = orm.relationship(
        ProductInfo,
        secondary=product_info_to_product_profile_association_table,
        secondaryjoin=sa.and_(
            ProductInfo.sku
            == orm.foreign(product_info_to_product_profile_association_table.c.sku),
            ProductInfo.account_id
            == orm.foreign(product_info_to_product_profile_association_table.c.account_id),
        ),
        secondaryjoin=(
            id
            == orm.foreign(product_info_to_product_profile_association_table.c.product_profile_id)
        ),
        backref=orm.backref("product_profile", uselist=False),
    )

这是当我尝试通过实例访问关系时生成的SQL

>>> pp.product_infos

[SELECT product_info.sku..........
FROM product_info, tpl_products_to_product_profiles_r1 
WHERE tpl_products_to_product_profiles_r1.product_profile_id = %s AND product_info.sku = tpl_products_to_product_profiles_r1.sku AND product_info.account_id = tpl_products_to_product_profiles_r1.account_id]
[parameters: (6L,)]

0 个答案:

没有答案