gpt4 book ai didi

python - 如何使用多级/多连接在 SQLAlchemy 中指定表关系?

转载 作者:太空狗 更新时间:2023-10-29 17:48:09 25 4
gpt4 key购买 nike

我正在尝试定义两个间接关系(即通过其他两个表)的表之间的关系。

我正在寻找的结果可以通过这个查询获取:

(db.session.query(Telnum)
.filter(Account.customer==customer)
.filter(Account.account_id == Subscription.account_id)
.filter(Telnum.sub_id == Subscription.id)
.order_by(Telnum.telnum)
.all()
)

其中 customer 是一个 Customer 对象。

我正在努力弄清楚如何将其定义为一种关系,类似于 Customer.invoices 关系。我的想法是这样的:

telnums = db.relationship('Telnum',
primaryjoin="and_(Account.user_id==Customer.id, "
"Account.account_id == Subscription.account_id, "
"Telnum.sub_id == Subscription.id)",
backref='customer')

正如这篇文章所表明的那样,这是行不通的。它产生的错误信息是这样的:sqlalchemy.exc.ArgumentError:无法找到任何简单的相等表达式,涉及主要连接条件的本地映射外键列 'accounts.user_id = customers.id AND accounts.account_id = subscriptions.account_id AND pstn_numbers.sub_id = subscriptions.id ' 在关系 Customer.telnums 上。确保引用列与 ForeignKey 或 ForeignKeyConstraint 相关联,或者在连接条件中使用 foreign() 注释进行注释。要允许“==”以外的比较运算符,可以将关系标记为 viewonly=True。

谁能给我指明正确的方向?

我有以下表结构(经过简化,所有不相关的列都从每个表中删除一列):

class Customer(db.Model):
__tablename__ = 'customers'
id = db.Column(db.Integer, primary_key=True)
identification_num = db.Column(db.String(10), unique=True)
name = db.Column(db.Text)
invoices = db.relationship('Invoice', backref='customer')
accounts = db.relationship('Account', backref='customer')

def __init__(self):
pass

def __repr__(self):
return '<Customer %r>' % (self.name)

class Invoice(db.Model):
__tablename__ = 'invoices'
id = db.Column(db.Integer, primary_key=True)
customer_id = db.Column(db.Integer, db.ForeignKey('customers.id'))
active = db.Column(db.Boolean)
accounts = db.relationship('Account', backref='invoice')

def __repr__(self):
return '<Invoice %r>' % (self.id)

class Account(db.Model):
__tablename__ = 'accounts'
id = db.Column(db.Integer, primary_key=True)
account_id = db.Column(db.Integer, unique=True)
invoice_id = db.Column(db.Integer, db.ForeignKey('invoices.id'))
user_id = db.Column(db.Integer, db.ForeignKey('customers.id'))
active = db.Column(db.Boolean)
subscriptions = db.relationship('Subscription', backref='account')

def __repr__(self):
return '<Account %r>' % (self.account_id)

class Subscription(db.Model):
__tablename__ = 'subscriptions'
id = db.Column(db.Integer, primary_key=True)
account_id = db.Column(db.Integer, db.ForeignKey('accounts.account_id'))
sub_active = db.Column(db.DateTime)
telnums = db.relationship('Telnum', backref='subscription')

def __repr__(self):
return '<Subscription %r>' % (self.id)

class Telnum(db.Model):
__tablename__ = 'pstn_numbers'
id = db.Column(db.Integer, primary_key=True)
sub_id = db.Column(db.Integer, db.ForeignKey('subscriptions.id'))
telnum = db.Column(db.String(64))
holder = db.Column(db.String(10))

def __repr__(self):
return '<Telnum %r>' % (self.telnum)

最佳答案

一般来说,我不会将间接关系定义为关系,因为您冒着这些间接关系变得不同步的风险当您进行修改时。您可以通过指定 viewonly=False 来解决其中的一些限制。 关系的参数。

一个更简单、风险更小、更直接的解决方案是使用查询(或启用查询的属性),以防您想从数据库中重新加载数据,并使用 python 列表推导来获取子-关系树的子子节点:

class Customer(Base):
# ...

@property
def telnums_qry(self):
sess = Session.object_session(self)
return (sess.query(Telnum)
.join(Subscription)
.join(Account)
.filter(Account.user_id == self.id)
).all()


@property
def telnums_mem(self):
return [tel
for acc in self.accounts
for sub in acc.subscriptions
for tel in sub.telnums
]


class Telnum(Base):
# ...

@property
def customer(self):
return (self.subscription
and self.subscription.account
and self.subscription.account.customer
)

关于python - 如何使用多级/多连接在 SQLAlchemy 中指定表关系?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22229099/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com