Great, adding the primary_key=True to the linkTypes table solved my problem,
thank you very much...

Cheers...

E.Ozgur Yilmaz
Lead Technical Director
eoyilmaz.blogspot.com
www.ozgurfx.com


On Tue, Jan 11, 2011 at 5:24 PM, Michael Bayer <mike...@zzzcomputing.com>wrote:

>
> On Jan 11, 2011, at 8:51 AM, Erkan Özgür Yılmaz wrote:
>
> Hi all,
>
> This is my first question regarding to SQLAlchemy, you can count me as a
> newbie. Here is my problem:
>
> I've this inheritance between my Python classes, everything were working
> fine until last night when I've added another class to my inheritance
> hierarchy. I've tried to find the cause of that pretty much read all the
> documentation about session, but couldn't find any solution.
>
> I'm going to try to reduce the things I'm writing here by not including all
> the attributes/methods below, so warn me if you spot something:
>
> This is the basic inheritance to let you figure out what is inheriting from
> what:
>
>
>
> There's a subtle configuration problem here that is causing the mapper to
> create the entity in the database in a way that throws it off when it goes
> to get it back.    Ticket #2019 is added for a warning to be emitted
> corresponding to this condition.   "linkTypes" has no primary key column, so
> that when the mapper inserts the rows for LinkType, it doesn't insert into
> the final "linkTypes" table.    Later, when you access .name,
> "sound_link_type" has been expired, which is the default behavior after a
> commit, and the mapper goes to load its data from all of its tables.    No
> row is present in linkTypes, so the load returns nothing and the mapper
> assumes the identity key has been deleted.
>
> I'd also note that you probably don't need all those "inherit_condition"
> parameters, those are figured out automatically based on foreign keys - only
> if there are multiple ways to join between parent and child tables, and the
> mapper throws an error, do you need to use that param.
>
>
> class SimpleEntity(object):
>     pass
>
> class Entity(SimpleEntity):
>     pass
>
> class TypeEntity(Entity):
>     pass
>
> class LinkType(TypeEntity):
>     pass
>
>
>
> Here are the Tables (just the ones used with these classes, there are a lot
> other tables too, I can paste them here if you ask for):
>
> # SIMPLE ENTITY
> simpleEntities = Table(
>     "simpleEntities", metadata,
>     Column("id", Integer, primary_key=True),
>     Column("name", String(256), nullable=False),
>     Column("description", String),
>
>     Column(
>         "created_by_id",
>         Integer,
>         ForeignKey("users.id", use_alter=True, name="x")
>     ),
>
>     Column(
>         "updated_by_id",
>         Integer,
>         ForeignKey("users.id", use_alter=True, name="x")
>     ),
>
>     Column("date_created", DateTime),
>     Column("date_updated", DateTime),
>     Column("entity_type", String(128), nullable=False),
>     UniqueConstraint('name', 'entity_type')
>
> )
>
>
> # ENTITY
> entities = Table(
>     "entities", metadata,
>     Column(
>         "id",
>         ForeignKey("simpleEntities.id"),
>         primary_key=True
>     ),
> )
>
>
>
> # TYPEENTITIES
> typeEntities = Table(
>     "typeEntities", metadata,
>     Column(
>         "id",
>         Integer,
>         ForeignKey("entities.id"),
>         primary_key=True,
>     ),
> )
>
>
> # LINKTYPES
> linkTypes = Table(
>     "linkTypes", metadata,
>     Column(
>         "id",
>         Integer,
>         ForeignKey("typeEntities.id"),
>     ),
> )
>
>
>
> Mappers:
>
>     # SimpleEntity
>     mapper(
>         entity.SimpleEntity,
>         tables.simpleEntities,
>         properties={
>             "_name": tables.simpleEntities.c.name,
>             "name": synonym("_name"),
>             "_description": tables.simpleEntities.c.description,
>             "description": synonym("_description"),
>             "_created_by": relationship(
>                 user.User,
>                 backref="_entities_created",
>                 primaryjoin=tables.simpleEntities.c.created_by_id== \
>                             tables.users.c.id,
>                 post_update=True,
>                 uselist=False
>             ),
>             "created_by": synonym("_created_by"),
>             "_updated_by": relationship(
>                 user.User,
>                 backref="_entities_updated",
>                 primaryjoin=tables.simpleEntities.c.updated_by_id== \
>                             tables.users.c.id,
>                 post_update=True,
>                 uselist=False
>             ),
>             "updated_by": synonym("_updated_by"),
>             "_date_created": tables.simpleEntities.c.date_created,
>             "date_created": synonym("_date_created"),
>             "_date_updated": tables.simpleEntities.c.date_updated,
>             "date_updated": synonym("_date_updated")
>         },
>         polymorphic_on=tables.simpleEntities.c.entity_type,
>         polymorphic_identity="SimpleEntity"
>     )
>
>
>     # Entity
>     mapper(
>         entity.Entity,
>         tables.entities,
>         inherits=entity.SimpleEntity,
>         inherit_condition=tables.entities.c.id==tables.simpleEntities.c.id
> ,
>         polymorphic_identity="Entity",
>         properties={
>             "_tags": relationship(
>                 tag.Tag,
>                 secondary=tables.entity_tags,
>                 backref="_entities"
>             ),
>             "tags": synonym("_tags")
>         }
>     )
>
>
>     # TypeEntity
>     mapper(
>         entity.TypeEntity,
>         tables.typeEntities,
>         inherits=entity.Entity,
>         inherit_condition=tables.typeEntities.c.id==tables.entities.c.id,
>         polymorphic_identity="TypeEntity",
>     )
>
>
>
>     # LinkType
>     mapper(
>         types.LinkType,
>         tables.linkTypes,
>         inherits=entity.TypeEntity,
>         inherit_condition=tables.linkTypes.c.id==tables.typeEntities.c.id,
>         polymorphic_identity="LinkType",
>     )
>
>
>
> Alright here it comes slowly, my session object is set up in another module
> (like the classes, tables and mappers are all in seperate modules), but I'm
> going to try to merge them here:
>
> >>> engine = create_engine("sqlite:///:memory:", "echo":True)
>
> here are calls for the mappers shown above:
> >>> mappers.setup()
> >>> create_all(engine)
> >>> Session = sessionmaker(bind=engine)
> >>> session = Session()
>
> >>> sound_link_type = LinkType(name="Sound")
> >>> sound_linkt_type.__dict__
> {'_created_by': None, '_sa_instance_state':
> <sqlalchemy.orm.state.InstanceState object at 0x19866d0>, '_description':
> '', '_date_updated': datetime.datetime(2011, 1, 11, 15, 44, 27, 954088),
> '_date_created': datetime.datetime(2011, 1, 11, 15, 44, 27, 954074),
> '_tags': [], '_name': 'Sound', '_nice_name': 'sound', '_updated_by': None}
>
> >>> session.add(sound_link_type)
> >>> session.commit()
> 2011-01-11 15:46:23,955 INFO sqlalchemy.engine.base.Engine.0x...8f50 BEGIN
> (implicit)
> 2011-01-11 15:46:23,956 INFO sqlalchemy.engine.base.Engine.0x...8f50 INSERT
> INTO "simpleEntities" (name, description, created_by_id, updated_by_id,
> date_created, date_updated, entity_type) VALUES (?, ?, ?, ?, ?, ?, ?)
> 2011-01-11 15:46:23,957 INFO sqlalchemy.engine.base.Engine.0x...8f50
> ('Sound', '', None, None, '2011-01-11 15:44:27.954074', '2011-01-11
> 15:44:27.954088', 'LinkType')
> 2011-01-11 15:46:23,960 INFO sqlalchemy.engine.base.Engine.0x...8f50 INSERT
> INTO entities (id) VALUES (?)
> 2011-01-11 15:46:23,961 INFO sqlalchemy.engine.base.Engine.0x...8f50 (3,)
> 2011-01-11 15:46:23,962 INFO sqlalchemy.engine.base.Engine.0x...8f50 INSERT
> INTO "typeEntities" (id) VALUES (?)
> 2011-01-11 15:46:23,962 INFO sqlalchemy.engine.base.Engine.0x...8f50 (3,)
> 2011-01-11 15:46:23,964 INFO sqlalchemy.engine.base.Engine.0x...8f50 COMMIT
>
>
> >>> sound_link_type.__dict__
> {'_sa_instance_state': <sqlalchemy.orm.state.InstanceState object at
> 0x19866d0>, '_nice_name': 'sound'}
>
>
> >>> sound_link_type.name
> 2011-01-11 15:47:00,570 INFO sqlalchemy.engine.base.Engine.0x...8f50 BEGIN
> (implicit)
> 2011-01-11 15:47:00,571 INFO sqlalchemy.engine.base.Engine.0x...8f50 SELECT
> "simpleEntities".description AS "simpleEntities_description",
> "simpleEntities".date_updated AS "simpleEntities_date_updated",
> "simpleEntities".date_created AS "simpleEntities_date_created",
> "simpleEntities".name AS "simpleEntities_name", "simpleEntities".id AS
> "simpleEntities_id", entities.id AS entities_id, "typeEntities".id AS
> "typeEntities_id", "linkTypes".id AS "linkTypes_id",
> "simpleEntities".created_by_id AS "simpleEntities_created_by_id",
> "simpleEntities".updated_by_id AS "simpleEntities_updated_by_id",
> "simpleEntities".entity_type AS "simpleEntities_entity_type"
> FROM "simpleEntities" JOIN entities ON entities.id = "simpleEntities".id
> JOIN "typeEntities" ON "typeEntities".id = entities.id JOIN "linkTypes" ON
> "linkTypes".id = "typeEntities".id
> WHERE "simpleEntities".id = ?
> 2011-01-11 15:47:00,571 INFO sqlalchemy.engine.base.Engine.0x...8f50 (3,)
> 2011-01-11 15:47:00,832 INFO sqlalchemy.engine.base.Engine.0x...8f50 SELECT
> "simpleEntities".description AS "simpleEntities_description",
> "simpleEntities".date_updated AS "simpleEntities_date_updated",
> "simpleEntities".date_created AS "simpleEntities_date_created",
> "simpleEntities".name AS "simpleEntities_name", "simpleEntities".id AS
> "simpleEntities_id", entities.id AS entities_id, "typeEntities".id AS
> "typeEntities_id", "linkTypes".id AS "linkTypes_id",
> "simpleEntities".created_by_id AS "simpleEntities_created_by_id",
> "simpleEntities".updated_by_id AS "simpleEntities_updated_by_id",
> "simpleEntities".entity_type AS "simpleEntities_entity_type"
> FROM "simpleEntities" JOIN entities ON entities.id = "simpleEntities".id
> JOIN "typeEntities" ON "typeEntities".id = entities.id JOIN "linkTypes" ON
> "linkTypes".id = "typeEntities".id
> WHERE "simpleEntities".id = ?
> 2011-01-11 15:47:00,832 INFO sqlalchemy.engine.base.Engine.0x...8f50 (3,)
> sqlalchemy.orm.exc.ObjectDeletedError: Instance '<LinkType at 0x19865d0>'
> has been deleted.
>
>
> any idea ??? (also for the sake of brevity I didn't include the echoed
> lines when I call create_all, I can send it too if it will help)
>
> E.Ozgur Yilmaz
> Lead Technical Director
> eoyilmaz.blogspot.com
> www.ozgurfx.com
>
> --
> You received this message because you are subscribed to the Google Groups
> "sqlalchemy" group.
> To post to this group, send email to sqlalch...@googlegroups.com.
> To unsubscribe from this group, send email to
> sqlalchemy+unsubscr...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/sqlalchemy?hl=en.
>
>
>  --
> You received this message because you are subscribed to the Google Groups
> "sqlalchemy" group.
> To post to this group, send email to sqlalch...@googlegroups.com.
> To unsubscribe from this group, send email to
> sqlalchemy+unsubscr...@googlegroups.com<sqlalchemy%2bunsubscr...@googlegroups.com>
> .
> For more options, visit this group at
> http://groups.google.com/group/sqlalchemy?hl=en.
>

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

Reply via email to