【问题标题】:How to avoid adding duplicates in a many-to-many relationship table in SQLAlchemy - python?如何避免在 SQLAlchemy - python 的多对多关系表中添加重复项?
【发布时间】:2013-04-08 17:45:27
【问题描述】:

我正在处理与 sqlalchemy 的多对多关系。我的问题是如何避免在多对多关系表中添加重复的对值。

为了让事情更清楚,我将使用官方 SQLAlchemy 文档中的示例。

Base = declarative_base()

Parents2children = Table('parents2children', Base.metadata,                                                                                                                                                                                                     
  Column('parents_id', Integer, ForeignKey('parents.id')),                                                                                                                                                                                                       
  Column('children_id', Integer, ForeignKey('children.id'))
)

class Parent(Base):
    __tablename__ = 'parents'
    id = Column(Integer, primary_key=True)
    parent_name = Column(String(45))
    child_rel = relationship("Child", secondary=Parents2children, backref= "parents_backref") 

    def __init__(self, parent_name=""):
        self.parent_name=parent_name
    def __repr__(self):
        return "<parents(id:'%i', parent_name:'%s')>" % (self.id, self.parent_name)

class Child(Base):
    __tablename__ = 'children'
    id = Column(Integer, primary_key=True)
    child_name = Column(String(45))

    def __init__(self, child_name=""):
        self.child_name= child_name
    def __repr__(self):
        return "<experiments(id:'%i', child_name:'%s')>" % (self.id, self.child_name)

###########################################

def setUp():
    global Session
    engine=create_engine('mysql://root:root@localhost/db_name?charset=utf8', pool_recycle=3600,echo=False)
    Session=sessionmaker(bind=engine)

def add_data():
    session=Session()
    name_father1=Parent(parent_name="Richard")
    name_mother1=Parent(parent_name="Kate")
    name_daughter1=Child(child_name="Helen")
    name_son1=Child(child_name="John")

    session.add(name_father1)
    session.add(name_mother1)

    name_father1.child_rel.append(name_son1)
    name_daughter1.parents_backref.append(name_father1)
    name_son1.parents_backref.append(name_father1)

    session.commit()
    session.close()


setUp()
add_data()
session.close()

使用此代码,插入表中的数据如下:

父母表

+----+-------------+
| id | parent_name |
+----+-------------+
|  1 | Richard     |
|  2 | Kate        |
+----+-------------+

儿童桌

+----+------------+
| id | child_name |
+----+------------+
|  1 | Helen      |
|  2 | John       |
+----+------------+

Parents2children 表

+------------+-------------+
| parents_id | children_id |
+------------+-------------+
|          1 |           1 |
|          1 |           2 |
|          1 |           1 |
+------------+-------------+

如您所见,最后一个表中有重复项...如何防止 SQLAlchemy 添加这些重复项?

我试过把关系(“Child”,secondary=...,collection_class=set显示这个错误: em>

AttributeError: 'InstrumentedSet' object has no attribute 'append'

【问题讨论】:

  • 您不能在重新添加之前检查关系是否已经存在吗?

标签: python sqlalchemy many-to-many duplicates unique


【解决方案1】:

PrimaryKeyConstraint(或UniqueConstraint)添加到您的relationship 表中:

Parents2children = Table('parents2children', Base.metadata,                                                                                                                                                                                                     
  Column('parents_id', Integer, ForeignKey('parents.id')),                                                                                                                                                                                                       
  Column('children_id', Integer, ForeignKey('children.id')),
  PrimaryKeyConstraint('parents_id', 'children_id'),
)

当您尝试提交从双方添加的关系时,您的代码将生成错误。非常推荐这样做。

为了不产生错误,请先检查:

if not(name_father1 in name_son1.parents_backref):
    name_son1.parents_backref.append(name_father1)

【讨论】:

  • 这几乎可以工作 :) 但是我如何防止 SQL Alchemy 在“children”表中添加相同的条目??
  • “避免在“children”表中添加相同条目的解决方案是什么?
猜你喜欢
  • 2011-09-27
  • 1970-01-01
  • 1970-01-01
  • 2016-11-22
  • 2015-10-21
  • 2018-11-12
  • 2019-10-03
  • 1970-01-01
  • 2017-10-29
相关资源
最近更新 更多