Flask SQLAlchemy跨3个模型和一个表结构连接

2024-05-06 02:41:58 发布

您现在位置:Python中文网/ 问答频道 /正文

我有三种型号:

class Customer(Model):
    __tablename__ = 'customer'

    id = Column(Integer, primary_key=True)
    statemented_branch_id = Column(Integer, ForeignKey('branch'))
    ...

class Branch(Model):
    __tablename__ = 'branch'

    id = Column(Integer, primary_key=True)
    ...

class SalesManager(Model):
    __tablename__ = 'sales_manager'

    id = Column(Integer, primary_key=True)
    branches = relationship('Branch', secondary=sales_manager_branches)

还有一个表格结构:

sales_manager_branches = db.Table(
    'sales_manager_branches',
    Column('branch_id', Integer, ForeignKey('branch.id')),
    Column('sales_manager_id', Integer, ForeignKey('sales_manager.id'))
)

我希望能够获得一个SalesManager的所有Customers,这意味着在任何Branch关系中拥有statemented_branch_id的所有客户。

我的问题看起来有点像这样:

branch_alias = aliased(Branch)
custs = Customer.query.join(branch_alias, SalesManager.branches).\
        filter(Customer.statemented_branch_id == branch_alias.id)

这显然是不对的。

我怎样才能得到一个SalesManager的所有Customers

更新

当我尝试:

Customer.query.\
         join(Branch).\
         join(SalesManager.branches).\
         filter(SalesManager.id == 1).all()

我收到一个操作错误:

*** OperationalError: (OperationalError) ambiguous column name: branch.id u'SELECT
customer.id AS customer_id, customer.statemented_branch_id AS 
customer_statemented_branch_id \nFROM customer JOIN branch ON branch.id 
customer.statemented_branch_id, "SalesManager" JOIN sales_manager_branches AS 
sales_manager_branches_1 ON "SalesManager".id = sales_manager_branches_1.sdm_id JOIN 
branch ON branch.id = sales_manager_branches_1.branch_id \nWHERE "SalesManager".id = ?'
(1,)

Tags: branchidmodelmanagercolumnintegercustomerclass
2条回答

我需要添加一个backref到我的SalesManager模型中,它允许SQLAlchemy计算如何从SalesManager到分支。

class SalesManager(Model):
    __tablename__ = 'sales_manager'

    id = Column(Integer, primary_key=True)
    branches = relationship(
        'Branch', secondary=sales_manager_branches, backref="salesmanagers")

然后像这样构造查询:

Customer.query.\
         join(Branch).\
         join(Branch.salesmanagers).\
         filter(SalesManager.id == 1).all()

尝试:

SalesManager.query \
            .join(Branch) \
            .join(Customer) \
            .filter(SalesManager.id == 123)

您可能需要通过join的第二个参数提供显式的on参数,或者可能需要显式地在中添加映射表,但在这两种情况下,您要做的是:

SELECT SM.*
FROM sales_manager SM
JOIN sales_manager_branches SMB
    ON SM.id = SMB.sales_manager_id
JOIN branch B
    ON SMB.branch_id = B.id
JOIN customer C
    ON B.id = C.statemented_branch_id
WHERE -- Conditions go here

相关问题 更多 >