2013-04-16 39 views
11

我正在處理與sqlalchemy的多對多關係。我的問題是如何避免在多對多關係表中添加重複對值。如何避免在SQLAlchemy的多對多關係表中添加重複項 - python?

爲了讓事情更清晰,我將使用來自官方的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:[email protected]/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中添加這些重複?

我試圖把關係( 「孩子」,二次= ...,collection_class =設置但會顯示此錯誤:

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

不能你檢查的關係已經存在,重新添加過嗎? – user1451340

回答

6

添加​​(或一個UniqueKeyConstraint)到您的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) 
+1

,幾乎可以工作:)但我怎麼能阻止SQL Alchemy在「children」表中添加相同的條目,例如? –

相關問題