Mike Bayer <mike...@zzzcomputing.com> writes:

> I'm not sure if you're using the ORM, there are some neat new hooks in 1.0
> that could be used for this, but let's assume you're doing pure Core.

Yes, that's exactly my use case (btw, that's because I'm using an async
approach, similar to Alchimia but based on asyncio rather than Twisted).

I will study the ORM part when it comes the need, but hopefully by that time I
will move to some better database and better schemas too, for example taking
advantage of something like sqlalchemy-i18n... :-)

> def replace_lang(stmt, lang):
>     def replace(obj):
>         if isinstance(obj, Column):
>             if obj.shares_lineage(products.c.en):
>                 return obj.table.c[lang]
>             elif obj.shares_lineage(products.c.en_note):
>                 return obj.table.c['%s_note' % lang]
>         return None
>
>     return sql.visitors.replacement_traverse(stmt, {}, replace)

This works great indeed, thank you for pointing me to the replacement facility!

The main drawback of your solution, applied to my case, is that there are many
tables containing such fields, and many "xx_yyyy" fields, so it is somewhat
impractical using shares_lineage().

I've come up with a variation, that assume I mark the "pivot" fields ("en"
and "en_note", for example) so that I can recognize them:

    from sqlalchemy import Table, Column, Integer, String, MetaData, select
    from sqlalchemy import sql

    m = MetaData()
    products = Table(
        'products',
        m,
        Column('id', Integer),
        Column('en', String, info={'localizable': True}),
        Column('it', String),
        Column('fr', String),

        Column('en_note', String, info={'localizable': True}),
        Column('it_note', String),
        Column('fr_note', String),
    )

    def replace_lang(stmt, lang):
        def replace(obj):
            if isinstance(obj, Column):
                if obj.info.get('localizable', False) or (
                        hasattr(obj.table, 'original') and
                        obj.table.original.c[obj.name].info.get('localizable', 
False)):
                    return obj.table.c[lang + obj.name[2:]]
            return None

        return sql.visitors.replacement_traverse(stmt, {}, replace)


    pc = products.c

    stmt = select([
        pc.id, pc.en.label('description'), pc.en_note.label('summary')
    ])

    print(replace_lang(stmt, 'it'))


    pca = products.alias().c
    stmt = select([
        pca.en.label('description'), pca.en_note.label('summary')
    ])

    print(replace_lang(stmt, 'it'))

Is it reasonable, or does the "table.original" trick fall short in corner
cases?

Thanks a lot,
ciao, lele.
-- 
nickname: Lele Gaifax | Quando vivrò di quello che ho pensato ieri
real: Emanuele Gaifas | comincerò ad aver paura di chi mi copia.
l...@metapensiero.it  |                 -- Fortunato Depero, 1929.

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

Reply via email to