flask-sqlalchemy 关系中的多个连接条件

问题描述 投票:0回答:1

我的数据库架构中有一个简单的外键链接,我想使用关系来访问所有链接的行。这是我的问题的精简版本:

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
这里的方法是错误的吗,或者它可以工作吗?

sqlalchemy flask-sqlalchemy
1个回答
0
投票

这看起来像两个一对多的关系。我认为您不能为此使用常规关系,因为它无法用于正确持久化到数据库,特别是如果

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"
    )

© www.soinside.com 2019 - 2024. All rights reserved.