On 06/15/2016 01:01 AM, Nick Whyte wrote:
Hey,

I'm working on a more complex problem with the ORM functionality of SQLA.

I have a reasonably simple relationship, ie,

class A(Base):
    id = sa.Column(sa.Integer(), primary_key=True)
    b_collection = sa.orm.relationship('B')


class B(Base):
    id = sa.Column(sa.Integer(), primary_key=True)
    a_id = sa.Column(sa.Integer(), sa.ForeignKey('a.id',
ondelete='CASCADE'))
    a = sa.orm.relationship('A')

    c_id = sa.Column(sa.Integer(), sa.ForeignKey('c.id',
ondelete='CASCADE'))
    c = sa.orm.relationship('C')

class C(Base):

    id = sa.Column(sa.Integer(), primary_key=True)
    newvalue = ?? ??

And I query the model like so, and iterate and access via the relationships.

obj = session.query(A).first()

I'm at a point now where I need to add a bit more information to "C",
during the time of query - ie, this depends on the web request context,
so (i don't think), /column_property /will work for me.

This extra information is in the form of a sa.select() which returns
tuples of (c.id, c.newvalue). I can easily do a join on these two when
querying C directly, ie: /session.query(C,
extra_info.c.newvalue).join().... /However, it seems doing this with
nested collections is a bit harder.

One option (which I think I may have to end up taking) is going to be
iterating the entire extra info query, and store it in a dict, and
iterate through every C record in the relationship, however this isn't
going to be as performant as I would like.

I've attempted to work with /contains_eager/, however this doesn't seem
to work for non-relationship fields, which is what this new field would
ideally end up being, in the sense of the ORM.

It seems deferred might be able to help me out here, but there doesn't
seem to be any API that allows me to load into a deferred property from
a higher level query.

Any suggestions would be great, and hopefully help me stop tearing me
hair out!

I can think of various things to do here but I need more context. How are the C records being loaded in the first place? I see you saying "session.query(A).first()" - so there are no eager loads of B, no eager loads of C at all to start with ? Is this the lazy load that incurs when you access the B.c attribute of each member in A.b_collection (that's also lazy loaded?)

Basically need to know where B.c is getting loaded, as well as some insight on what kind of query we are talking about. If a lazy load, then I would suggest a custom deferred query option that will install "c.newvalue" into the lazy load query as well. There's a long term issue (can be shorter term if interest is apparent) to allow a flexible style of "deferred" attribute that can be plugged with any value https://bitbucket.org/zzzeek/sqlalchemy/issues/3058/allow-to-inject-expression-based-columns however there are other ways to get this effect - most easily, you can use bindparam() objects in a column_property() that you can set up at query time.






Cheers!

--
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
<mailto:sqlalchemy+unsubscr...@googlegroups.com>.
To post to this group, send email to sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>.
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

--
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 https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Reply via email to