I have been using the automap extension with postgres, with an inheritance
structure using the joined inheritance pattern. I could not figure out a
way to have this reflected from the DB so I define the classes for this
part of my schema explicitly, and when automap initializes, these classes
get used (and modified) for those tables and the rest get autogenerated.
It works fine until I try to delete an instance of an inheriting class:
then I get a circular dependency error which seems to relate to
relationships and backreferences created for the foreign key relationship
underlying the joined inheritance.
The attached code demonstrates the issue. The first run generates the DB
schema from the classes, and works, any number of times. On the second
run, switch the two comments for Base (in two places) to use automap. The
output of the first:
% ./test.py
RELATIONSHIPS: []
Run completed successfully.
% ./test.py
RELATIONSHIPS: [('employee', RelationshipProperty at 0x10263d310;
employee), ('engineer_collection', RelationshipProperty at 0x102663210;
engineer_collection)]
Circular dependency detected. Cycles: {DeleteState(Engineer at
0x1026a9d10)} all edges: {(DeleteState(Engineer at 0x1026a9d10),
DeleteState(Engineer at 0x1026a9d10)),
(ProcessState(OneToManyDP(Employee.engineer_collection), Engineer at
0x1026a9d10, delete=True), DeleteState(Engineer at 0x1026a9d10))}
Notice that the mapper in the first case shows no relationships, despite
the foreign key created for the inheritance. On the other hand when the
same structure is read from the DB by automap, we see forward and back
relationships, which I guess is somehow causing the circular dependency.
Am I doing something wrong in my attempt to use joined inheritance in
conjunction with automap, or is this a bug or something unsupported?
--
You received this message because you are subscribed to the Google Groups
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.
#!/usr/bin/env python
from sqlalchemy import Column, Integer, String, create_engine
from sqlalchemy.ext.automap import automap_base
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy.schema import ForeignKey
# SWITCH commenting here and below to test
Base = declarative_base()# Run 1
#Base = automap_base(declarative_base=declarative_base())# Run 2
class Employee(Base):
__tablename__ = 'employee'
id = Column(Integer, primary_key=True)
name = Column(String(50))
type = Column(String(50))
__mapper_args__ = {
'polymorphic_identity':'employee', 'polymorphic_on':type
}
class Engineer(Employee):
__tablename__ = 'engineer'
id = Column(Integer, ForeignKey('employee.id'), primary_key=True)
engineer_name = Column(String(30))
__mapper_args__ = {
'polymorphic_identity':'engineer',
}
engine = create_engine(postgresql://user:pw@localhost/test)
Session = sessionmaker(bind=engine)
# SWITCH commenting to test
Base.metadata.create_all(engine)# Run 1
#Base.prepare(engine, reflect=True)# Run 2
# Test
session = Session()
engineer = Engineer(engineer_name='Eng 1', name='Emp 1')
print(RELATIONSHIPS: + str(engineer.__mapper__.relationships.items()))
session.add(engineer)
session.commit()
session = Session()
engineer = session.query(Engineer).all()[0]
session.delete(engineer)
try:
session.commit()
print(Run completed successfully)
except Exception as e:
print(EXCEPTION: + str(e))