我的数据库架构中有一个简单的外键链接,我想使用关系来访问所有链接的行。这是我的问题的精简版本:
from flask_sqlalchemy import SQLAlchemy
from flask import Flask
db: SQLAlchemy = SQLAlchemy()
app = Flask(__name__, instance_relative_config=True)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///database_name.db'
db.init_app(app)
class Child(db.Model):
id = db.Column(db.Integer, primary_key=True)
parent_id = db.Column(db.Integer, db.ForeignKey("Parent.id"))
parent = db.relationship("Parent")
class ToyShare(db.Model):
id = db.Column(db.Integer, primary_key=True)
child_id = db.Column(db.Integer, db.ForeignKey("child.id"), nullable=False)
time = db.Column(db.Float)
class Parent(db.Model):
id = db.Column(db.Integer, primary_key=True)
toy_shares = db.relationship(
"ToyShare",
primaryjoin="Child.parent_id == Parent.id",
)
但是,当我尝试以任何方式使用
toy_shares
属性时,我得到
sqlalchemy.exc.ArgumentError: Could not locate any simple equality expressions involving locally mapped foreign key columns for primary join condition 'child.parent_id = parent.id' on relationship Parent.toy_shares. Ensure that referencing columns are associated with a ForeignKey or ForeignKeyConstraint, or are annotated in the join condition with the foreign() annotation. To allow comparison operators other than '==', the relationship can be marked as viewonly=True.
我尝试了一些诸如
foreign_keys=[Child.parent_id, ToyShare.child_id]
和辅助连接之类的事情,但无法正确使用 relationship
。该错误消息让我感到困惑,因为链接 Parent
和 ToyShare
的外键看起来很简单。
relationship
这里的方法是错误的吗,或者它可以工作吗?
这看起来像两个一对多的关系。我认为您不能为此使用常规关系,因为它无法用于正确持久化到数据库,特别是如果
Child
有其他列。您可以添加 viewonly 关系,但我不确定这是否值得。它与尝试在多对多关系中跳过辅助表/类有类似的问题,本节关联对象中讨论。
为什么不能只使用常规关系来访问
ToyShare
对象? select(ToyShare).join(ToyShare.child).join(Child.parent)
?
class Child(db.Model):
__tablename__ = 'childs'
id = db.Column(db.Integer, primary_key=True)
parent_id = db.Column(db.Integer, db.ForeignKey("parents.id"))
parent = db.relationship("Parent", back_populates="childs")
toy_shares = db.relationship(
"ToyShare", back_populates="child"
)
class ToyShare(db.Model):
__tablename__ = 'toy_shares'
id = db.Column(db.Integer, primary_key=True)
child_id = db.Column(db.Integer, db.ForeignKey("childs.id"), nullable=False)
time = db.Column(db.Float)
child = db.relationship(
"Child", back_populates="toy_shares"
)
class Parent(db.Model):
__tablename__ = 'parents'
id = db.Column(db.Integer, primary_key=True)
childs = db.relationship(
"Child", back_populates="parent"
)