On Aug 26, 2013, at 3:43 PM, Florian Rüchel <florian.ruec...@gmail.com> wrote:
> Hey there, > > I have already posted this on stackoverflow but not recieved an answer yet so > I thought I might try here. To quote from my original question: I've seen it, and the issue is that the question is difficult to parse. > > > Suppose we have these classes: > > class Item(Base): > id = Column(Integer, primary_key=True) > data = Column(String) > i18ns = relationship("ItemI18n", backref="item") > > class ItemI18n(Base): > lang_short = Column(String, primary_key=True) > item_id = Column(Integer, ForeignKey('item.id'), primary_key=True) > name = Column(String) > [on pastebin] > > > The idea here is to have this item's name in multiple languages, for example > in English and German. This works fine so far, one can easily work with that. > However, most times, I am not interested in all (i.e. both) names but only > the users locale. > > For example, if the user is English and wants to have the name in his > language, I see two options: > > # Use it as a list > item = session.query(Item).first() > print item.data, [i18n.name for i18n in item.i18ns if i18n.lang_short == > "en"][0] > > # Get the name separately > item, name = session.query(Item, > ItemI18N.name).join(ItemI18N).filter(ItemI18N.lang_short == "en").first() > print item.data, name Based on detail further down, I know what you want, but reading this was confusing. You mean "item" should offer its .name attribute in multiple languages, right? How would that be possible without using a method? otherwise how are you instructing the Item object as to what language you'd like? > > But business logic is different: I would expect to have an `Item` with a > `name` and `description` attribute, so that I would do something like this: > > item = session.query(Item).first() > print item.data, item.name This doesn't make any sense - where is "description" above? what does it do? > > So that's where I want to go: Pull all those attributes from `Item18N` > directly into `Item`. how are you specifying which Item18N you want? "pulling attributes" is very easy and there are several approaches but only if you have the two objects to start with. > And of course, I would have to specify the language anywhere. where's "anywhere"? > > def name(self, locale): OK here I see we finally have a "name" function with a locale, great ! > > But this is not a pretty solution, both because of the overhead of retrieving > all I18N data from the database and then fitering that result back to one > thus making it completely irrelevant that I pulled all in the first place Why do you need to retrieve all of the data? why not just retrieve the one you want? def name(self, locale): return object_session(self).query(ItemI18N.name).with_parent(self).filter(ItemI18N.locale == locale).scalar() with_parent is one of the helper operators mentioned in the tutorial: http://docs.sqlalchemy.org/en/rel_0_8/orm/tutorial.html?highlight=with_parent#common-relationship-operators if you didn't know about with_parent, this works too: def name(self, locale): return object_session(self).query(ItemI18N.name).filter(self.id == ItemI18N.item_id).filter(ItemI18N.locale == locale).scalar() there are also ways to turn this into a relationship() and use eager loading if that helps, slightly less simple.
signature.asc
Description: Message signed with OpenPGP using GPGMail