I created a gist that recreates the issue when running SQLAlchemy 
1.1.0b3: https://gist.github.com/Javex/41c58b098c1e5736cb2b21c4b6708be3

Traceback (most recent call last):
  File "broken_autojoin.py", line 73, in <module>
    print('Title: %s' %article.german.title)
  File 
"/home/javex/.virtualenvs/mtc3/lib/python3.5/site-packages/sqlalchemy/orm/attributes.py",
 
line 237, in __get__
    return self.impl.get(instance_state(instance), dict_)
  File 
"/home/javex/.virtualenvs/mtc3/lib/python3.5/site-packages/sqlalchemy/orm/attributes.py",
 
line 584, in get
    value = self.callable_(state, passive)
  File 
"/home/javex/.virtualenvs/mtc3/lib/python3.5/site-packages/sqlalchemy/orm/strategies.py",
 
line 553, in _load_for_state
    passive
  File 
"/home/javex/.virtualenvs/mtc3/lib/python3.5/site-packages/sqlalchemy/orm/strategies.py",
 
line 589, in _get_ident_for_use_get
    for pk in self.mapper.primary_key
  File 
"/home/javex/.virtualenvs/mtc3/lib/python3.5/site-packages/sqlalchemy/orm/strategies.py",
 
line 589, in <listcomp>
    for pk in self.mapper.primary_key
KeyError: Column('language_id', Integer(), ForeignKey('language.id'), 
table=<article_i18n>, primary_key=True, nullable=False)

Let me know if this breaks for you as well. If this is in fact a bug (and 
not some stupid mistake I made) and you happen to create an issue / fix for 
this I'd also be interested in seeing how it was fixed and where the 
problem was, so please link it here if possible so I can follow it :)

Cheers,
Florian

On Sunday, 7 August 2016 23:58:04 UTC+10, Mike Bayer wrote:
>
>
>
> On 08/06/2016 08:03 PM, Florian Rüchel wrote: 
> > Following up on this. I have implemented it in my application and it 
> > works beautifully when querying for the object. 
> > 
> > However, while writing tests, I discovered that if the object is 
> > expired, it doesn't know how to refresh it. To explain the issue, I need 
> > to expand my original (simplified) example. The MyObjI18N class doesn't 
> > store the locale directly. Instead it has another foreignkey to a 
> > Language table. So my query in the above case looks actually like this: 
> > 
> > and_(MyObj.id == MyObjI18N.obj_id, request.language_id == Language.id) 
> > 
> > Now the problem is this: It doesn't seem to remember this language_id 
> > when refreshing, leading to the following exception: 
> > 
> > .../python3.5/site-packages/sqlalchemy/orm/attributes.py:237: in __get__ 
> >     return self.impl.get(instance_state(instance), dict_) 
> > .../python3.5/site-packages/sqlalchemy/orm/attributes.py:584: in get 
> >     value = self.callable_(state, passive) 
> > .../python3.5/site-packages/sqlalchemy/orm/strategies.py:553: in 
> > _load_for_state 
> >     passive 
> > .../python3.5/site-packages/sqlalchemy/orm/strategies.py:589: in 
> > _get_ident_for_use_get 
> >     for pk in self.mapper.primary_key 
> > _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
> > _ _ _ 
> > 
> > .0 = <tuple_iterator object at 0x7fe545dc97b8> 
> > 
> >     get_attr( 
> >         state, 
> >         dict_, 
> >         self._equated_columns[pk], 
> >         passive=passive) 
> >>   for pk in self.mapper.primary_key 
> >             ] 
> > E           KeyError: Column('language_id', Integer(), 
> > ForeignKey('language.id'), table=<challenge_i18n>, primary_key=True, 
> > nullable=False) 
> > 
> > .../python3.5/site-packages/sqlalchemy/orm/strategies.py:589: KeyError 
> > 
> > I dug into the problem a bit but this goes way more into the core of 
> > SQLAlchemy than I am able to understand. In the end it seemed to be that 
> > on the join condition the lazy clause created didn't contain the equated 
> > column for language_id. But here my understanding of the working 
> > internals comes to an end. 
> > 
> > I would have assumed that the instance somehow 'remembered' that column 
> > from when it was loaded and would refresh it in the same way as it was 
> > loaded. And from the setup, I feel like it should be possible. My best 
> > guess would be that the primaryjoin I return doesn't help it 
> > 'understand' that it has that link to a language_id column. 
>
> I can't see how that would happen unless we're talking about something 
> like clear_mappers().  the construction of SQL expressions and their 
> linkages to mappers do not change with "expiration", and the recipe uses 
> a bindparameter() object that similarly doesn't change. 
>
> I can offer no insight here without complete specifics. 
>
>
>
> > 
> > FWIW I am running SQLAlchemy 1.1.0b3, in case this is actually 
> > unexpected behaviour. 
> > 
> > Cheers, 
> > Florian 
> > 
> > On Friday, 5 August 2016 00:24:30 UTC+10, Mike Bayer wrote: 
> > 
> > 
> > 
> >     On 08/04/2016 10:14 AM, Florian Rüchel wrote: 
> >     > I have a relationship that depends on a query time variable to 
> >     determine 
> >     > the correct join. The use case is request-time localization in a 
> web 
> >     > application. When running the query during a request, I want to 
> >     > determine the locale and only load the translation for the current 
> >     > language for a given object. However, the primaryjoin condition 
> >     callable 
> >     > is evaluated at mapping time instead which only happens once 
> >     instead of 
> >     > on every request. 
> >     > 
> >     > Here is a quick sample: 
> >     > 
> >     > def get_myobj_primaryjoin(): 
> >     >     return and_(MyObj.id == MyObjI18N.obj_id, request.locale == 
> >     > MyObjI18N.lang) 
> >     > 
> >     > 
> >     > class MyObj(Base): 
> >     >     id = Column(Integer, primary_key=True) 
> >     >     _current_translation = relationship(MyObjI18N, uselist=False, 
> >     > primaryjoin=get_myobj_primaryjoin, lazy='joined') 
> >     > 
> >     > 
> >     > class MyObjI18N(Base): 
> >     >     obj_id = Column(ForeignKey(MyObj.id), primary_key=True) 
> >     >     lang = Column(String) 
> >     > 
> >     > This should give a rough idea of the issue: request.locale changes 
> at 
> >     > query time, that is, if I do MyObj.query in two different 
> >     requests, it 
> >     > won't work, it will always take the first time it was called. 
> >     > 
> >     > Note that I was previously using a with_transformation approach 
> when 
> >     > building the query but I wanted to remove the necessity to add 
> that 
> >     > every time a build a query and would have it much rather built 
> >     implicitly. 
> >     > 
> >     > Any ideas are highly appreciated, no argument I can pass to 
> >     > "relationship" seems to help my use case. 
> > 
> > 
> >     we use a bound parameter for this and a recipe for getting a value 
> in 
> >     there can be seen at 
> >     
> https://bitbucket.org/zzzeek/sqlalchemy/wiki/UsageRecipes/GlobalFilter 
> >     <
> https://bitbucket.org/zzzeek/sqlalchemy/wiki/UsageRecipes/GlobalFilter> 
> >     . 
> >         In particular the lazyload case can only be affected using a 
> custom 
> >     MapperOption as described near the bottom of that recipe. 
> > 
> > 
> > 
> >     > 
> >     > -- 
> >     > 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+...@googlegroups.com <javascript:> 
> >     > <mailto:sqlalchemy+unsubscr...@googlegroups.com <javascript:> 
> <javascript:>>. 
> >     > To post to this group, send email to sqlal...@googlegroups.com 
> >     <javascript:> 
> >     > <mailto:sqlal...@googlegroups.com <javascript:>>. 
> >     > Visit this group at https://groups.google.com/group/sqlalchemy 
> >     <https://groups.google.com/group/sqlalchemy>. 
> >     > For more options, visit https://groups.google.com/d/optout 
> >     <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+...@googlegroups.com <javascript:> 
> > <mailto:sqlalchemy+unsubscr...@googlegroups.com <javascript:>>. 
> > To post to this group, send email to sqlal...@googlegroups.com 
> <javascript:> 
> > <mailto:sqlal...@googlegroups.com <javascript:>>. 
> > 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