python SQLAlchemy多对多唯一约束仅以一种方式工作

Posted

技术标签:

【中文标题】python SQLAlchemy多对多唯一约束仅以一种方式工作【英文标题】:python SQLAlchemy many to many unique constraint only working one way 【发布时间】:2018-05-21 18:09:41 【问题描述】:

我在烧瓶应用程序中使用带有 sqlAlchemy 的 python 2.7 和 sqllite,并尝试映射两个模型之间的关系,模型是 Lad 和 Crew,Lad 可以有很多工作人员,反之亦然,唯一的限制是这对应该是唯一的,例如一个小伙子只能在一个船员中,反之亦然,我已经建立了模型,并且当尝试将一个船员添加到同一个小伙子两次时,主键约束限制了我,但是当试图将同一个小伙子两次添加到船员中,让我,这也应该被禁止。

peopleInCrews = Table("peopleInCrewsAssosiation", Base.metadata,
                      Column("A", Integer, ForeignKey("lads.id", ondelete="CASCADE", onupdate="CASCADE"), primary_key=True),
                      Column("B", Integer, ForeignKey("crews.id", ondelete="CASCADE", onupdate="CASCADE"), primary_key=True),
                      PrimaryKeyConstraint("A", "B"))


class Lad(Base):
    __tablename__ = 'lads'
    id = Column(Integer, primary_key=True, autoincrement=True)
    firstName = Column(String(50), unique=False)
    lastName = Column(String(50), unique=False)

    crews = relationship("Crew", secondary=peopleInCrews, back_populates="lads")



class Crew(Base):
    __tablename__ = 'crews'
    id = Column(Integer, primary_key=True, autoincrement=True)

    name = Column(String(20), unique=False)

    lads = relationship("Lad", secondary = peopleInCrews, back_populates = "crews")#, cascade = "all, delete")

当我开始创建一个小伙子和一个船员时,如下所示:

c = Crew("name") 
l = Lad("first", "last")

以下代码会引发重复错误:

c.lads.append(lad)
c.lads.append(lad)

下面的代码预计会做同样的事情,但只是将小伙子两次添加到 cramp.lads 中:

l.crews.append(c)
l.crews.append(c) 

我在这里缺少什么?

编辑: 有人建议这个问题类似于this 一个,这里的不同之处在于我使用的是primaryKeyConstraint,并且它在一个方向上工作而不是在另一个方向上工作。例如您可以将同一个小伙子添加到 Lad.crews 中两次,但您不能将同一个小伙子添加到 Crew.lads 中。它应该是一个对称的唯一约束,并且两种方式都一样。

【问题讨论】:

这里 l =Lad("first","last") 将创建一个具有新 id 的新对象。所以从技术上讲,它把它当作一个新的对象,因此允许它。值可能相同,但对象不同。有意义吗? Why don't duplicates in a relationship violate a UniqueConstraint?的可能重复 @mad_ 我将同一个对象添加两次并创建一次,我认为这不是这里的问题 @univerio 我没有使用唯一的约束而是primarykeyconstraint,这不是一个重复 @thebeancounter PRIMARY KEYs 几乎等同于 UNIQUE CONSTRAINTs。该问题的要点是,除非您使用collection_class=set,否则您不应将相同的对象添加到相同的关系中。 【参考方案1】:

问题解决了

db_session.add(c)
db_session.add(l)
c.lads.append(lad)
c.lads.append(lad)
l.crews.append(c)
l.crews.append(c)
db_session.refresh(lad)
db_session.refresh(c) 

它没有提供异常,但它解决了对象内部的重复。

【讨论】:

以上是关于python SQLAlchemy多对多唯一约束仅以一种方式工作的主要内容,如果未能解决你的问题,请参考以下文章

如何避免在 SQLAlchemy - python 的多对多关系表中添加重复项?

python中flask和sqlalchemy的多对多

Python SQLAlchemy之多对多

SQLAlchemy 增删改查 一对多 多对多

Flask SQLAlchemy 多对多关联对象错误

SQLAlchemy 增删改查 一对多 多对多