2017-09-29 4 views
0

je tente de supprimer des données, mais sqlalchemy a essayé de le faire deux fois, et rollback base Postgresql Version 9.6 sqlalchemy 1.0.14 psycopg2 2.7.3.1sqlalchemy beaucoup à plusieurs Postgresql doubles supprimer

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

Et maintenant, nous avons trouvé une exception

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

données d'exception

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

n'avez pas trouvé sur d'autres réponses

Répondre

0

Ceci est dû à la fois specifying parts of the Declarative classes explicitly à la main et à l'aide automapper par rapport aux tables existantes. Les relations que vous définissez manuellement ne pas utiliser la convention de nommage par défaut utilisé par le automapper, et il crée une autre version de la relation:

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

Ainsi, lorsque vous émettez votre suppression, les relations feu leurs cascades, et vous obtenez 2 instructions DELETE. relations prépondérants est particulièrement mentionné dans la documentation:

Ci-dessus, l'un des détails les plus complexes est que nous avons illustré l'un des remplaçant relationship() objets qu'Automap aurait créé. Pour ce faire, nous devions nous assurer que les noms correspondent à ce que Automap normalement générer, en ce que le nom de la relation serait User.address_collection ...

Pour résoudre ce problème soit revenir à l'aide du schéma de nommage par défaut, ou provide your own:

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

puis

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

Merci, il est des œuvres! –

+0

Je suis désolé, je n'utilise autobase que pour le prototype. Sur declare_base je n'ai pas utilisé la fonction de préparation. Est-ce que cela fonctionne sur déclarer la base? –

+0

Vous ne serez pas exécuté avec le déclaratif "plain", car il ne génère pas automatiquement de relations. –