Thnx a lot Alex! I already love Pylons and SQLAlchemy!

On 23 Wrz, 12:16, Alex K <[EMAIL PROTECTED]> wrote:
> Hello, here is the answer:
>
> # -*- coding: utf-8 -*-
>
> from sqlalchemy import create_engine
> from sqlalchemy import Table, Column, Integer, String, Unicode,
> MetaData, ForeignKey
> from sqlalchemy.orm import sessionmaker, mapper,
> dynamic_loader,backref, relation, composite, comparable_property,
> contains_eager,aliased
> from sqlalchemy.sql import text, and_
> from orm.object.factory import make_papped_class
> from sqlalchemy.orm import PropComparator
>
> from common import Application
>
> app = Application()
> session = app.session
> metadata = app.metadata
>
> """
> Book :
> isbn -> integer
> translations -> many translations
> prices -> many prices
>
> Translation :
> book -> FK to book
> laguage -> FK to Language (oneTOone)
> title -> string
>
> Language :
> code -> string
> name  -> string
>
> Currency :
> code -> string
> name -> string
>
> Price :
> currency -> FK
> book ->FK
> brutto -> int
> netto -> int
>
> """
>
> book_table = Table('book', metadata,
>                     Column('isbn', Integer, primary_key=True)
>                     )
>
> language_table = Table('language', metadata,
>                     Column('code', String(5), primary_key=True),
>                     Column('name', Unicode(20)),
>                     )
>
> currency_table = Table('currency', metadata,
>                     Column('code', String(5), primary_key=True),
>                     Column('name', Unicode(20)),
>                     )
>
> translation_table = Table('translation', metadata,
>                     Column('book_id', Integer,
> ForeignKey(book_table.c.isbn)),
>                     Column('language_id', String(5),
> ForeignKey(language_table.c.code)),
>                     Column('title', Unicode(512)),
>                     )
>
> price_table = Table('price', metadata,
>                     Column('currency_id', String(5),
> ForeignKey(currency_table.c.code)),
>                     Column('book_id', Integer,
> ForeignKey(book_table.c.isbn)),
>                     Column('brutto', Integer),
>                     Column('netto', Integer)
>                     )
>
> metadata.create_all()
>
> #create objects
> class Book(object):
>     def __init__(self,isbn):
>         self.isbn = isbn
>
> class Language(object):
>     def __init__(self,code,name):
>         self.code = code
>         self.name = name
>
> class Currency(object):
>     def __init__(self,code,name):
>         self.code = code
>         self.name = name
>
> class Translation(object):
>     def __init__(self,book_id,language_id,title):
>         self.book_id = book_id
>         self.language_id = language_id
>         self.title = title
>
> class Price(object):
>     def __init__(self,currency_id,book_id,brutto,netto):
>         self.currency_id = currency_id
>         self.book_id = book_id
>         self.brutto = brutto
>         self.netto = netto
>
> mapper(Book,book_table)
> mapper(Language,language_table)
> mapper(Currency,currency_table)
>
> mapper(Translation,translation_table,properties = {
>     'book': relation(Book,
>                      lazy = False, #1 note lazy here, it means that
> we
>                                    # will use lazy loading (more
> details in the docs
>                      backref = backref('translations',lazy = False)),
>     'language': relation(Language,
>                          uselist = False,#2 note uselist, it means
>                                          #we use one-to-one instead of
> one-to-many
>                          lazy = False),},
>
> primary_key = [translation_table.c.book_id,
>                translation_table.c.language_id]
> #explicit primary key is needed when SQLA can not assemble the one for
> you automatically
> );
>
> mapper(Price,price_table,properties = {
>     'currency': relation(Currency,lazy = False),
>     'book': relation(Book,lazy = False, backref =
> backref('prices',lazy = False))
>
> },primary_key = [price_table.c.book_id,price_table.c.currency_id]);
>
> session = app.session
>
> if False: #change this to True to issue add statement
>     session.add(Language('en',u'English'))
>     session.add(Language('ru',u'Русский'))
>
>     session.add(Currency('usd',u'Dollar'))
>     session.add(Currency('rub',u'Рубль'))
>
>     session.add(Book(1))
>     session.add(Book(2))
>
>     session.flush()
>
>     session.add(Translation(book_id = 1, language_id = 'en', title =
> u'The book'))
>     session.add(Translation(book_id = 1, language_id = 'ru', title =
> u'Книжка'))
>
>     session.add(Translation(book_id = 2, language_id = 'en', title =
> u'Book'))
>     session.add(Translation(book_id = 2, language_id = 'ru', title =
> u'Книжка2'))
>
>     session.add(Price(book_id = 1, currency_id = 'usd', brutto = 12,
> netto = 20))
>     session.add(Price(book_id = 1, currency_id = 'rub', brutto = 250,
> netto = 500))
>
>     session.add(Price(book_id = 2, currency_id = 'usd', brutto = 10,
> netto = 18))
>     session.add(Price(book_id = 2, currency_id = 'rub', brutto = 200,
> netto = 440))
>
> """
>  would like now to get books that:
> isbn>1
> translation.title in english starts with "The" ( I don't need other
> languages for this select)
> price.netto < 100 USD ( I don't need other prices, only in USD for
> this select)
>
> There are 5 Tables to join.
> Lets say I have 100 objects maching,  I dont want to hit the db 100
> times.
> """
>
> # the common approach here, as Michael says,
> # is to construct the query as you would do it yourself
> # and to tel sql alchemy where to pick the data for objects from
>
> #aliases to control the query
> ATranslation =  aliased(Translation)
> APrice =  aliased(Price)
>
> books = session.query(Book)\
>             .outerjoin((ATranslation,Book.translations))\
>             .outerjoin((APrice,Book.prices))\
>             .filter(and_(
>                          Book.isbn >= 1,
>                          ATranslation.language_id == 'en',
>                          ATranslation.title.like(u'The%'),
>                          APrice.currency_id == 'usd',
>                          APrice.netto < 25,))\
>             .options(contains_eager('translations',alias =
> ATranslation))\
>             .options(contains_eager('prices',alias = APrice))
>
> """
>     .outerjoin((ATranslation,Book.translations)) - creates explicit
> join to the named alias,
>     and tells that this join implements Book.translations relation
>
>     ATranslation.language_id == 'en', - now we can use the named alias
> to issue filter statements
>
>     .options(contains_eager('translations',alias = ATranslation)) -
> now refer to the note #1,
>     this statement says to SQLA that it needs to load data for the
> translation relation from this alias
>
> """
>
> """
> at the end the query gives you the following statement (MySQL):
>
> SELECT  book.isbn AS book_isbn,
>         currency_1.code AS currency_1_code,
>         currency_1.name AS currency_1_name,
>         price_1.currency_id AS price_1_currency_id,
>         price_1.book_id AS price_1_book_id,
>         price_1.brutto AS price_1_brutto,
>         price_1.netto AS price_1_netto,
>         language_1.code AS language_1_code,
>         language_1.name AS language_1_name,
>         translation_1.book_id AS translation_1_book_id,
>         translation_1.language_id AS translation_1_language_id,
>         translation_1.title AS translation_1_title
> FROM book
>         LEFT OUTER JOIN translation AS translation_1
>             ON book.isbn = translation_1.book_id
>         LEFT OUTER JOIN price AS price_1
>             ON book.isbn = price_1.book_id
>         LEFT OUTER JOIN currency AS currency_1
>             ON currency_1.code = price_1.currency_id
>         LEFT OUTER JOIN language AS language_1
>             ON language_1.code = translation_1.language_id
> WHERE
>     translation_1.language_id = %s
>     AND translation_1.title LIKE %s
>     AND price_1.currency_id = %s
>     AND price_1.netto < %s
>
> with the bind args as:
>     ['en', 'The%', 'rub', 25]
>
> If it's not what you expected, let me know
> """
>
> #now when you access the results, SQLA issues no additional queries
> for you
> print [(book.isbn, book.translations[0].title,book.prices[0].netto,)
> for book in books]
>
> """
> a helper application class used in this example (from common import
> Application)
>
> class Application(object):
>
>     url =  URL( drivername = 'mysql',
>             username = 'root',
>             password = '',
>             host = 'localhost',
>             port = '3306',
>             database = 'test',
>             query = {'charset':'utf8'})
>
>     def __init__(self,echo = True):
>         engine = create_engine(Application.url,encoding = 'utf-8',echo
> = echo)
>         Session = sessionmaker(bind=engine)
>         self.session = Session()
>         self.metadata = MetaData()
>         self.metadata.bind = self.session.connection()
>
>     def close(self):
>         self.session.commit()
>         self.session.close()
>
> """
>
> app.close()
>
> On Sep 22, 10:25 pm, g00fy <[EMAIL PROTECTED]> wrote:
>
> > I have this problem with setting relations with specific models:
>
> > Book :
> > isbn -> integer
> > translations -> many translations
> > prices -> many prices
>
> > Translation :
> > book -> FK to book
> > laguage -> FK to Language (oneTOone)
> > title -> string
>
> > Language :
> > code -> string
> > name  -> string
>
> > Currency :
> > code -> string
> > name -> string
>
> > Price :
> > currency -> FK
> > book ->FK
> > brutto -> int
> > netto -> int
>
> > so those are my models.
>
> > I would like now to get books that:
> > isbn>1
> > translation.title in english starts with "The" ( I don't need other
> > languages for this select)
> > price.netto < 100 USD ( I don't need other prices, only in USD for
> > this select)
>
> > There are 5 Tables to join.
> > Lets say I have 100 objects maching,  I dont want to hit the db 100
> > times.
>
> > I am begginer in SQLAlchemy so please understand my maybe "Stupid"
> > question.
>
>
--~--~---------~--~----~------------~-------~--~----~
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