you have inter-row dependencies (where a "row" here represents a
joined row from base table to child table), which SQLAlchemy only
detects at the mapped object level, not the interdependent column
level (SQLA doesn't have any intelligence attached to the setting of
foreign key attributes). So you have to set the relationships between
A and B objects using the relation()s:
b1 = ChildB(key = "b1", data_b = "azerty", link_a=a1)
b2 = ChildB(key = "b2", data_b = "ytreza", link_a=a2)
from that, the unit of work detects that b1 and b2 are both dependent
on an A object, which then gets INSERTed first.
ironically, its the presence of the "link_a" relation that sets off
the "inter-row" dependency logic in the first place. If this relation
is set to viewonly=True, the UOW doesn't drop into inter-row
dependencies, and the order of INSERT among a particular set of
objects with a common base class is determined by the order in which
the objects where added to the session, so it works again.
On Mar 7, 2009, at 1:46 PM, Matthieu wrote:
> # -*- coding: utf-8 -*-
>
> # imports from sqlalchemy
> import sqlalchemy
> from sqlalchemy import create_engine, Table, Column, Text, MetaData,
> ForeignKey
> from sqlalchemy.sql import text
> from sqlalchemy.orm import mapper, relation, sessionmaker
>
> class BaseClass(object):
>
> def __init__(self,
> key = None,
> data = None,
> class_type = "BaseClass"):
> self.key = key
> self.data = data
> self.class_type = class_type
>
> class ChildA(BaseClass):
>
> def __init__(self,
> key = None,
> data_a = None,
> **kwargs):
> super(ChildA, self).__init__(key = key, class_type = "ChildA",
> **kwargs)
> self.data_a = data_a
>
> class ChildB(BaseClass):
>
> def __init__(self,
> key = None,
> data_b = None,
> key_child_a = None,
> **kwargs):
> super(ChildB, self).__init__(key = key, class_type = "ChildB",
> **kwargs)
> self.data_b = data_b
> self.key_child_a = key_child_a
>
> sqla_engine = create_engine("postgres:///sqla-test", echo = True)
> sqla_connexion = sqla_engine.connect()
> sqla_metadata = MetaData()
> sqla_metadata.bind = sqla_engine
> sqla_session_maker = sessionmaker(bind = sqla_engine, autoflush =
> True, autocommit = False)
> sqla_session = sqla_session_maker()
>
> base_class_table = Table(
> 'base_class',
> sqla_metadata,
> Column('key', Text, primary_key = True),
> Column('class_type', Text, nullable = False),
> Column('data', Text))
>
> child_a_table = Table(
> 'child_a',
> sqla_metadata,
> Column('key', Text, ForeignKey('base_class.key'), primary_key =
> True),
> Column('data_a', Text))
>
> child_b_table = Table(
> 'child_b',
> sqla_metadata,
> Column('key', Text, ForeignKey('base_class.key'), primary_key =
> True),
> Column('data_b', Text),
> Column('key_child_a', Text, ForeignKey(base_class_table.c.key)))
>
>
> drop_statment = text("""DROP TABLE "child_b"; DROP TABLE "child_a";
> DROP TABLE "base_class" """)
> sqla_connexion.execute(drop_statment)
> sqla_metadata.create_all()
>
>
> mapper(BaseClass,
> base_class_table,
> polymorphic_on = base_class_table.c.class_type,
> polymorphic_identity = "BaseClass")
>
> mapper(ChildA,
> child_a_table,
> inherits = BaseClass,
> polymorphic_identity = "ChildA")
>
> mapper(ChildB,
> child_b_table,
> inherits = BaseClass,
> inherit_condition = child_b_table.c.key ==
> base_class_table.c.key,
> polymorphic_identity = "ChildB",
> properties = {
> 'link_a':
> relation(ChildA,
> backref = 'links_b',
> primaryjoin = child_b_table.c.key_child_a ==
> base_class_table.c.key)})
>
> a1 = ChildA(key = "a1", data_a = "foo")
> sqla_session.add(a1)
> #sqla_session.flush()
> a2 = ChildA(key = "a2", data_a = "bar")
> sqla_session.add(a2)
> #sqla_session.flush()
> b1 = ChildB(key = "b1", data_b = "azerty", key_child_a = "a1")
> sqla_session.add(b1)
> #sqla_session.flush()
> b2 = ChildB(key = "b2", data_b = "ytreza", key_child_a = "a2")
> sqla_session.add(b2)
> sqla_session.flush()
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To post to this group, send email to [email protected]
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
-~----------~----~----~----~------~----~------~--~---