在SQLAlchemy中,如何正确使用insert()。from_select()构造?

时间:2013-11-21 19:43:45

标签: python sql insert sqlalchemy

我正在尝试创建一个简单的函数来呈现包含(dest_column,src_expression)对的dict。

特别是,我希望界面类似于:

insert_into(table_obj_a, tbl_object_b, dict(
    col_c = 'col_f',
    col_a = 'col_g',
    col_q = 'col_r + 5',
    col_r = tbl_object_b.col_q,
    col_m = 'rand()',
))

在尝试实现这一点时,我注意到.from_select功能的一些特殊行为,即传递给from_select的列的顺序似乎被忽略。

这就是我所遇到的:

bug.py

import sqlalchemy as sa

def _insert_into_dict(into_table, from_table, column_dict):
    into_keys = []
    from_vals = []
    for k, v in sorted((k, v) for (k, v) in column_dict.iteritems()):
        into_keys.append(k)
        from_vals.append(v)
    print into_keys
    print from_vals
    sel = sa.select(from_vals, from_obj=from_table)
    print sel
    print
    return into_table.insert().from_select(
        into_keys, sel
    )

md = sa.MetaData()

cols = ['aaaa', 'bbbb', 'dddd', 'eeee', 'ffff', 'aardvark']

print _insert_into_dict(
    sa.Table('table_a', md, *[sa.Column(x, sa.String) for x in cols]),
    sa.Table('table_b', md),
    dict(
        aaaa='aaaa',
        bbbb='bbbb',
        dddd='dddd',
        eeee='eeee',
        ffff='ffff',
        aardvark='aardvark',
    )
)

输出

u@host:~/src/sa_bug$ python bug.py
['aaaa', 'aardvark', 'bbbb', 'dddd', 'eeee', 'ffff']
['aaaa', 'aardvark', 'bbbb', 'dddd', 'eeee', 'ffff']
SELECT aaaa, aardvark, bbbb, dddd, eeee, ffff
FROM table_b

INSERT INTO table_a (aaaa, bbbb, dddd, eeee, ffff, aardvark) SELECT aaaa, aardvark, bbbb, dddd, eeee, ffff
FROM table_b

预期

u@host:~/src/sa_bug$ python bug.py
['aaaa', 'aardvark', 'bbbb', 'dddd', 'eeee', 'ffff']
['aaaa', 'aardvark', 'bbbb', 'dddd', 'eeee', 'ffff']
SELECT aaaa, aardvark, bbbb, dddd, eeee, ffff
FROM table_b

INSERT INTO table_a (aaaa, aardvark, bbbb, dddd, eeee, ffff) SELECT aaaa, aardvark, bbbb, dddd, eeee, ffff
FROM table_b

如您所见,INSERT INTO语句中列名的顺序与SELECT语句中表达式的顺序不匹配。

我是否误解了.from_select()的用途?

2 个答案:

答案 0 :(得分:2)

问题在于您定义into_table时这样:

sa.Table('table_a', md, *[sa.Column(x, sa.String) for x in cols])

cols列表没有排序,所以对于这个列表是完全正确的:

cols = ['aaaa', 'bbbb', 'dddd', 'eeee', 'ffff', 'aardvark']

INSERT SQL是:

INSERT INTO table_a (aaaa, bbbb, dddd, eeee, ffff, aardvark)

在您的功能中,您使用sorted()column_dict进行排序,因此您还必须对cols列表进行排序。只需尝试在cols.sort()定义后添加cols

之后INSERT SQL应为:

INSERT INTO table_a (aaaa, aardvark, bbbb, dddd, eeee, ffff)

答案 1 :(得分:0)

正如zzzeek所说,这是SQLAlchemy中的一个错误< 0.8.4。

http://www.sqlalchemy.org/trac/ticket/2895