Как указать столбцы с объединенными анонимно псевдонимными таблицами в SqlAlchemy - PullRequest
2 голосов
/ 29 декабря 2010

У меня возникают проблемы с определением правильного синтаксиса, который будет использоваться для правильного указания столбцов при запросах к объединенным таблицам, анонимным псевдонимам которых используется генерирующий синтаксис SqlAlchemy.

Схема содержит 2 таблицы, один ко многим:

user = Table('user', meta,
    Column('id', Integer, primary_key=True, autoincrement = False),
    Column('name', String),
    Column('department_id', Integer, ForeignKey('department.id'))
)

department = Table('department', meta,
    Column('id', Integer, primary_key=True, autoincrement = True),
    Column('name', String)
)

Один запрос к таблице работает:

# alias the tables anonymously
u = user.alias()
d = department.alias()

# single table select works
q = select([
    u.c.id.label('UserId'),
    u.c.name.label('User'),
    ])
r = conn.execute(q).fetchall()
log.debug(r[0].keys())
# [u'UserId', u'User']

Но при объединении таблиц с псевдонимами они переименовываются, и я не знаю, какими будут новые имена, поэтомуЯ не могу указать столбцы:

# join the 2 aliased tables
from_ = u.join(d)
log.debug(from_.c.keys())
# [u'%(172847020 user)s_id', u'%(172847020 user)s_name', u'%(172847020 user)s_department_id', u'%(172846668 department)s_id', u'%(172846668 department)s_name']

# this does not work
q = select([
    from_.c.user_id.label('UserId'),
    from_.c.user_name.label('User'),
    from_.c.department_name.label('Department'),
    ])
r = conn.execute(q).fetchall()
log.debug(r[0].keys())

Как мне заставить это работать?

Вот полный код теста:

import logging
from sqlalchemy import create_engine, Table, Column, Integer, String, MetaData, ForeignKey
from sqlalchemy.sql import *

log = logging.getLogger('generative_test')
logging.basicConfig(level=logging.DEBUG,
        format='%(asctime)s,%(msecs)03d %(levelname)s [%(filename)s.%(funcName)s @ %(lineno)d.%(thread)d] %(message)s')

engine = create_engine('sqlite:///:memory:', echo = False, echo_pool = False)
meta = MetaData()
meta.bind = engine

user = Table('user', meta,
    Column('id', Integer, primary_key=True, autoincrement = False),
    Column('name', String),
    Column('department_id', Integer, ForeignKey('department.id'))
)

department = Table('department', meta,
    Column('id', Integer, primary_key=True, autoincrement = True),
    Column('name', String)
)

meta.create_all(engine)
conn = engine.connect()

conn.execute(department.insert(),[
    {'name':'bosses'},
    {'name':'peons'},
])
conn.execute(user.insert(),[
    {'name':'Mr. Slate','department_id':1},
    {'name': 'Fred','department_id':2},
    {'name': 'Barney','department_id':2},
])

# alias the tables anonymously
u = user.alias()
d = department.alias()

# single table select works
q = select([
    u.c.id.label('UserId'),
    u.c.name.label('User'),
    ])
r = conn.execute(q).fetchall()
log.debug(r[0].keys())
# [u'UserId', u'User']

# join the 2 aliased tables
from_ = u.join(d)
log.debug(from_.c.keys())
# [u'%(172847020 user)s_id', u'%(172847020 user)s_name', u'%(172847020 user)s_department_id', u'%(172846668 department)s_id', u'%(172846668 department)s_name']

# this does not work
q = select([
    from_.c.user_id.label('UserId'),
    from_.c.user_name.label('User'),
    from_.c.department_name.label('Department'),
    ])
r = conn.execute(q).fetchall()
log.debug(r[0].keys())

1 Ответ

2 голосов
/ 29 декабря 2010
q = select([
    u.c.id.label('UserId'),
    u.c.name.label('User'),
    d.c.name.label('Department'),
], from_obj=u.join(d))
...