如何在SqlAlchemy中指定具有已加入的匿名别名表的列

时间:2010-12-29 15:32:35

标签: sql sqlalchemy alias

在使用SqlAlchemy的生成语法查询匿名别名的连接表时,我无法确定用于正确指定列的正确语法。

架构有两个表,一对多:

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 个答案:

答案 0 :(得分:2)

q = select([
    u.c.id.label('UserId'),
    u.c.name.label('User'),
    d.c.name.label('Department'),
], from_obj=u.join(d))