2013-04-16 4 views
11

Ich habe es mit einer Viele-zu-Viele-Beziehung zu sqlalchemy zu tun. Meine Frage ist, wie vermieden werden kann, doppelte Wertepaare in einer number-to-many relationalen Tabelle hinzuzufügen.Wie vermeidet man das Hinzufügen von Duplikaten in einer Viele-zu-Viele-Beziehungstabelle in SQLAlchemy - python?

Um die Dinge klarer zu machen, werde ich das Beispiel aus der offiziellen SQLAlchemy-Dokumentation verwenden.

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

Mit diesem Code werden die in den Tabellen eingefügt Daten ist die folgende:

Eltern Tabelle:

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

Kindertisch:

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

Parents2children Tisch

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

Wie Sie sehen können, gibt es ein Duplikat in der letzten Tabelle ... wie konnte ich verhindern SQLAlchemy aus diesen Duplikaten hinzufügen?

Ich habe versucht Beziehung zu setzen ("Child", sekundär = ..., collection_class = gesetzt) ​​aber dieser Fehler wird angezeigt:

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

konnte man nicht überprüfen, ob eine Beziehung existiert bereits, bevor es wieder hinzufügen? – user1451340

Antwort

6

ein In PrimaryKeyConstraint (oder ein UniqueKeyConstraint) auf Ihrer relationship Tabelle:

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

und Ihr Code wird einen Fehler erzeugen, wenn Sie versuchen, die von beiden Seiten hinzugefügte Beziehung begehen. Dies ist sehr zu empfehlen.

Um nicht einmal einen Fehler zu erzeugen, überprüfen gerade noch:

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

das funktioniert fast :) aber wie könnte ich verhindern, dass SQL Alchemy die gleichen Einträge in "Kinder" Tabelle zum Beispiel hinzufügen ?? –