Michael,

Thank you for reply.

Of course explicit object loading works well. The only problem is that
it actually executes a query, unless master instance is already
loaded. This can be avoided by building special INSERT statement
during flush(). Something like the following:

INSERT into details (master_id) values (select id from masters where
name=?)

It should be possible to generate such a query with little help from
programmer and that could lighten load on database especially when
there more than one foreign key and such objects are created very
often.

May be it is more wise not to use ORM and work with tables directly.

Cheers

On Apr 1, 12:20 am, Michael Bayer <[EMAIL PROTECTED]> wrote:
> On Mar 31, 2008, at 11:37 PM, askel wrote:
>
>
>
>
>
> > Hello everybody,
>
> > I'm wondering if there is a "standard" way of doing something like the
> > following:
>
> > masters = Table('masters', meta,
> > Column('id', Integer, primary_key=True),
> > Column('name', String, unique, nullable=False)
> > )
>
> > details = Table('details', meta,
> > Column('id', Integer, primary_key=True),
> > Column('master_id', Integer, ForeignKey('masters.id'),
> > nullable=False),
> > Column('name', String, nullable=False),
> > UniqueConstraint('master_id', 'name')
> > )
>
> > class Master(object): pass
>
> > mapper(Master, masters, properties={'details': relation(Detail)})
>
> > class Detail(object):
> > def __init__(self, master_name, name):
> >  '''Magic happens here
> >  assigning to master_name forces master_id to be magically resolved
> > later on, probably by MapperExtension
> >  '''
> >  self.master_name = master_name
> >  self.name = name
>
> > mapper(Detail, details, properties={'master': relation(Master)})
>
> The master_id FK attribute is populated upon flush(), when you've
> associated a Master and Detail object with each other beforehand.
>
> If you want to construct a Detail that loads its Master in, just do it
> in the constructor:
>
> class Detail(object):
>         def __init__(self, master_name, name):
>                 self.master =
> session.query(Detail).filter(Master.name==master_name).one()
>
> This kind of pattern tends to work nicely when you're using a thread-
> local ScopedSession so that theres no need to pass one into Detail's
> constructor.
>
> Also, the bidirectional relationship is better served by a single
> backref rather than two distinct properties:
>
> mapper(Detail, details)
> mapper(Master, masters, properties={'details': relation(Detail,
> backref='master')})
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to