繁体   English   中英

自我参照多对多烧瓶SQLAlchemy

[英]self referential many to many flask-sqlalchemy

我一生无法弄清为什么这种自指的多对多会不高兴:

minor_contains = db.Table(
    'minor_contains',
    db.Column('parent_id', db.Integer, db.ForeignKey('minors.id'),
            primary_key=True),
    db.Column('contains_id', db.Integer, db.ForeignKey('minors.id'),
            primary_key=True))

class Minor(db.Model):
    __tablename__ = 'minors'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String())
    ...
    contains = db.relationship(
        "Minor",
        secondary=minor_contains,
        primaryjoin="id == minor_contains.c.parent_id",
        secondaryjoin="id == minor_contains.c.contains_id",
        backref="contained_by",
        lazy='dynamic')

我已经尝试过根据针对SQLAlchemy和Flask-SQLAlchemy看到的示例以几种不同的方式对它进行重做,但是我始终会遇到以下错误消息,或者最终陷入无限循环。

E ArgumentError:无法在关系Minor.contains上找到涉及本地联接条件'minor_contains.parent_id =:parent_id_1'的涉及本地映射外键列的任何简单等式表达式。 确保引用列与ForeignKey或ForeignKeyConstraint关联,或在联接条件中使用foreign()注释进行注释。 要允许除“ ==”以外的比较运算符,可以将该关系标记为viewonly = True。

更新

我真的无法理解该错误消息,因为它显示了连接表中的列与其自身进行比较,其中连接的条件应该是未成年人表的PK与连接表中的FK相比。

我还将添加一个永久挂起的版本。 您会看到我一直在修改变量名,这样就一遍又一遍地重写它,希望如果我重新尝试一下它,那么第二或第五次我会变得更聪明。

minor_contains = db.Table(
    'minor_contains',
    db.Column('parent_minor_id', db.Integer, db.ForeignKey('minors.id'),
            primary_key=True),
    db.Column('contains_minor_id', db.Integer, db.ForeignKey('minors.id'),
            primary_key=True))

class Minor(db.Model):
    __tablename__ = 'minors'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String())
    ...
    contains = db.relationship(
        "Minor",
        secondary=minor_contains,
        primaryjoin=id==minor_contains.c.parent_minor_id,
        secondaryjoin=id==minor_contains.c.contains_minor_id,
        backref=db.backref("minor_contains", lazy='dynamic'))

我认为有必要在连接条件中指定模型名称。

contains = db.relationship(
    "Minor",
    secondary=minor_contains,
    primaryjoin="Minor.id == minor_contains.c.parent_id",
    secondaryjoin="Minor.id == minor_contains.c.contains_id",
    backref=db.backref('minor_contains', lazy='dynamic'),
    lazy='dynamic')

我有同样的问题,它解决了这个问题。 我在这里找到了一个有用的答案: 链接

您是否尝试过这样做?

minor_contains = db.Table(
    'minor_contains',
    db.Column('parent_id', db.Integer, db.ForeignKey('minors.id'),
        primary_key=True),
    db.Column('contains_id', db.Integer, db.ForeignKey('minors.id'),
        primary_key=True))

class Minor(db.Model):
    __tablename__ = 'minors'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String())
    ...
    contains = db.relationship(
        "Minor",
        secondary=minor_contains,
        primaryjoin="id == minor_contains.c.parent_id",
        secondaryjoin="id == minor_contains.c.contains_id",
        backref=db.backref('minor_contains', lazy='dynamic'),
        lazy='dynamic')

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM