2017-09-29 1 views
0

ich versuchen, Daten zu löschen, aber sqlalchemy versuchte es zweimal zu tun, und Basis Postgresql Version 9.6 sqlalchemy 1.0.14 psycopg2 2.7.3.1sqlalchemy many-to-many Postgresql Doppel löschen

class IdentifiedObject(Base): 
    __tablename__ = 'identifiedobject' 
    mRID = Column(UUID, server_default=sqlalchemy.text("uuid_generate_v4()"), primary_key=True) 
    name = Column(String) 
    polymorphic_type = Column(String, nullable=False) 
    __mapper_args__={'polymorphic_identity':__tablename__,'polymorphic_on':polymorphic_type} 
assoc_1 = Table("assoc_1", Base.metadata, 
    Column("cars_mRID", None, ForeignKey("cars.mRID")), 
    Column("games_mRID", None, ForeignKey("games.mRID"))) 
class Cars(IdentifiedObject): 
    __tablename__='cars' 
    mRID = Column(None, ForeignKey('identifiedobject.mRID'), primary_key=True) 
    polymorphic_type = Column(String, nullable=False) 
    __mapper_args__={'polymorphic_identity':__tablename__,'inherit_condition': mRID == IdentifiedObject.mRID,'polymorphic_on':polymorphic_type} 
    status = Column(String) 
    Games = relationship("Games", secondary = "assoc_1", back_populates="Cars", primaryjoin="(cars.c.mRID==assoc_1.c.cars_mRID)") 
class Games(IdentifiedObject): 
    __tablename__='games' 
    mRID = Column(None, ForeignKey('identifiedobject.mRID'), primary_key=True) 
    polymorphic_type = Column(String, nullable=False) 
    __mapper_args__={'polymorphic_identity':__tablename__,'inherit_condition': mRID == IdentifiedObject.mRID,'polymorphic_on':polymorphic_type} 
    status = Column(String) 
    Cars = relationship("Cars", secondary = "assoc_1", back_populates="Games", primaryjoin="(games.c.mRID==assoc_1.c.games_mRID)") 

Base.metadata.create_all(engine) 
Base.prepare(engine, reflect=True) 
session = Session(bind=engine) 
session.add(IdentifiedObject()) 
games=Games(Cars=[Cars(),Cars()]) 
session.add (games) 
session.commit() 
session.close() 
session.delete(games) 
session.commit() 
Rollback

Und wir fanden jetzt eine Ausnahme

2017-09-29 09:17:44,996 INFO sqlalchemy.engine.base.Engine SELECT cars."mRID" AS "cars_mRID", identifiedobject."mRID" AS "identifiedobject_mRID", identifiedobject.name AS identifiedobject_name, cars.polymorphic_type AS cars_polymorphic_type, identifiedobject.polymorphic_type AS identifiedobject_polymorphic_type, cars.status AS cars_status 
FROM assoc_1, identifiedobject JOIN cars ON cars."mRID" = identifiedobject."mRID" 
WHERE %(param_1)s = assoc_1."games_mRID" AND cars."mRID" = assoc_1."cars_mRID" 
2017-09-29 09:17:44,996 INFO sqlalchemy.engine.base.Engine {'param_1': UUID('7a960989-5e3e-45dc-87c1-1b62ffa3694a')} 
2017-09-29 09:17:44,997 INFO sqlalchemy.engine.base.Engine DELETE FROM assoc_1 WHERE assoc_1."cars_mRID" = %(cars_mRID)s AND assoc_1."games_mRID" = %(games_mRID)s 
2017-09-29 09:17:44,998 INFO sqlalchemy.engine.base.Engine ({'games_mRID': UUID('7a960989-5e3e-45dc-87c1-1b62ffa3694a'), 'cars_mRID': UUID('a3135561-e416-45c0-b9f8-aead59ef6b34')}, {'games_mRID': UUID('7a960989-5e3e-45dc-87c1-1b62ffa3694a'), 'cars_mRID': UUID('b77b9dc4-65da-45ea-be52-dc53e2bcd74b')}) 
2017-09-29 09:17:44,998 INFO sqlalchemy.engine.base.Engine DELETE FROM assoc_1 WHERE assoc_1."cars_mRID" = %(cars_mRID)s AND assoc_1."games_mRID" = %(games_mRID)s 
2017-09-29 09:17:44,999 INFO sqlalchemy.engine.base.Engine ({'games_mRID': UUID('7a960989-5e3e-45dc-87c1-1b62ffa3694a'), 'cars_mRID': UUID('a3135561-e416-45c0-b9f8-aead59ef6b34')}, {'games_mRID': UUID('7a960989-5e3e-45dc-87c1-1b62ffa3694a'), 'cars_mRID': UUID('b77b9dc4-65da-45ea-be52-dc53e2bcd74b')}) 
2017-09-29 09:17:44,999 INFO sqlalchemy.engine.base.Engine ROLLBACK 
Traceback (most recent call last): 
    File "testing.py", line 98, in <module> 
    session.commit() 

Ausnahme Daten

sqlalchemy.orm.exc.StaleDataError: DELETE statement on table 'assoc_1' expected to delete 2 row(s); Only 0 were matched. 

Haben Sie nicht auf andere Antworten gefunden

Antwort

0

Dies sowohl specifying parts of the Declarative classes explicitly von Hand und mit AutoMapper gegen bestehende Tabellen verursacht wird. Die Beziehungen definieren Sie nicht manuell die Standardnamenskonvention durch die AutoMapper verwendet verwenden, und so schafft es eine andere Version der Beziehung:

In [8]: list(inspect(Games).relationships) 
Out[8]: 
[<RelationshipProperty at 0x7f932dea8ac8; Cars>, 
<RelationshipProperty at 0x7f932de6c2c8; cars_collection>] 

Also, wenn Sie Ihre Lösch ausgeben, beide Beziehungen feuern ihre Kaskaden, und Sie erhalten 2 DELETE-Anweisungen. Übergeordnete Beziehungen ist besonders in der Dokumentation erwähnt:

Oben, eine der komplizierten Details ist, dass wir die zwingende einem der relationship() Objekte dargestellt, die Automap geschaffen hätte. Dazu mussten wir sicherstellen, dass die Namen übereinstimmen mit dem, was automap normalerweise erzeugen, dass die Beziehung Name User.address_collection wäre ...

Um dies zu beheben, entweder setzen Sie den Standardnamensschema zu verwenden oder provide your own:

In [6]: def class_name_collection(base, local_cls, referred_cls, constraint): 
    ...:  return referred_cls.__name__ 
    ...: 

und dann

...: Base.prepare(engine, reflect=True, 
    ...:    name_for_collection_relationship=class_name_collection) 
+0

Dank, ist es funktioniert! –

+0

Es tut mir leid, ich benutze Autobase nur für den Prototyp. Auf declare_base habe ich Prepare-Funktion nicht verwendet. Funktioniert es auf Basis deklarieren? –

+0

Sie werden nicht mit dem deklarativen "plain" dazu kommen, da es nicht automatisch Beziehungen generiert. –

Verwandte Themen