On Aug 26, 2013, at 3:43 PM, Florian Rüchel <[email protected]> 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
