Just like you needed to use an ALTER statement to add the keys from Users->Objects, SQLA needs the same courtesy so it knows that no dependency should be stated when it inserts a row into all three tables for your User object. The INSERT of the user knows it must insert a row into three tables, so it wants to insert in their order of dependency. This is done for the full set of rows to be inserted for the "Object" hierarchy so it doesn't necessarily know that the OwnerUserID column is NULL in all cases. The list of tables needs a clue as to what their natural dependency order is since its ambiguous here (you could make the argument that their dependency order *is* unambiguous due to the mapping applied to them, so perhaps this would make a nice improvement at some point. in general this is a really rare occurence).
So autoload "Object" as follows: object_table = Table('Object', metadata, Column("OwnerUserID", Integer, ForeignKey("User.UserID", name='x', use_alter=True)), Column("LastModifiedUserID", Integer, ForeignKey("User.UserID", name='x', use_alter=True)), autoload = True, autoload_with=engine) the datatypes and foreign key names are not crucial here since you aren't issuing a CREATE TABLE. On Jun 4, 2008, at 10:54 AM, Marin wrote: > > I have a PostgreSQL database with 3 tables: Object, Role and User: > > CREATE TABLE "Object" > ( > "ObjectID" BIGINT NOT NULL DEFAULT NEXTVAL('"SEQ_ObjectID"'), > "ObjectTypeID" INT NOT NULL, > "OwnerUserID" BIGINT NOT NULL, > "CreatedTimestamp" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT > NOW(), > "LastModifiedUserID" BIGINT DEFAULT NULL, > CONSTRAINT "PK_Object" PRIMARY KEY ("ObjectID"), > CONSTRAINT "FK_Object_ObjectType" FOREIGN KEY ("ObjectTypeID") > REFERENCES "ObjectType"("ObjectTypeID") > ); > > CREATE TABLE "Role" > ( > "RoleID" BIGINT NOT NULL DEFAULT NEXTVAL('"SEQ_ObjectID"'), > CONSTRAINT "PK_Role" PRIMARY KEY ("RoleID"), > CONSTRAINT "FK_Role_Object" FOREIGN KEY ("RoleID") REFERENCES > "Object"("ObjectID") > ON DELETE CASCADE > ); > > CREATE TABLE "User" > ( > "UserID" BIGINT NOT NULL DEFAULT NEXTVAL('"SEQ_ObjectID"'), > CONSTRAINT "PK_User" PRIMARY KEY ("UserID"), > CONSTRAINT "FK_User_Role" FOREIGN KEY ("UserID") REFERENCES > "Role"("RoleID") > ON DELETE RESTRICT > ); > > ALTER TABLE "Object" > ADD CONSTRAINT "FK_Object_owner" FOREIGN KEY ("OwnerUserID") > REFERENCES "User"("UserID") > ON DELETE RESTRICT; > ALTER TABLE "Object" > ADD CONSTRAINT "FK_Object_last_modified" FOREIGN KEY > ("LastModifiedUserID") REFERENCES "User"("UserID") > ON DELETE RESTRICT; > > Then I reflect the tables: > object_table = sa.Table('Object', SA_Metadata, autoload = True, > autoload_with=engine) > role_table = sa.Table('Role', SA_Metadata, autoload = True, > autoload_with=engine) > user_table = sa.Table('User', SA_Metadata, autoload = True, > autoload_with=engine) > > And map them: > orm.mapper(db.Object, object_table, > polymorphic_on=object_table.c.ObjectTypeID, polymorphic_identity=1) > orm.mapper(db.Role, role_table, inherits=db.Object, > polymorphic_identity=2) > orm.mapper(db.User, user_table, inherits=db.Role, > polymorphic_identity=3) > > And when I try to insert a new User: > user = db.User() > user.OwnerUserID = 1 > db_session.save(user) > db_session.flush() > > I get this error: > sqlalchemy.exceptions.CircularDependencyError: Circular dependency > detected [(Role, User), (Object, Role), (User, Object)][] > > The tables are circular, but the UserID and OwnerUserID are never > identical for any User that SQLAlchemy should insert. I spent this > whole day looking for a solution, but there were none. > > > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~----------~----~----~----~------~----~------~--~---