【发布时间】:2018-04-17 03:53:20
【问题描述】:
在 SQLAlchemy 中,如何从 SELECT 语句填充或更新表?
【问题讨论】:
标签: python sqlalchemy
在 SQLAlchemy 中,如何从 SELECT 语句填充或更新表?
【问题讨论】:
标签: python sqlalchemy
SQLalchemy 不会为您构建这个结构。您可以使用文本查询。
session.execute('INSERT INTO t1 (SELECT * FROM t2)')
一年多过去了,但现在在 sqlalchemy 0.6+ you can create it:
from sqlalchemy.ext import compiler
from sqlalchemy.sql.expression import Executable, ClauseElement
class InsertFromSelect(Executable, ClauseElement):
def __init__(self, table, select):
self.table = table
self.select = select
@compiler.compiles(InsertFromSelect)
def visit_insert_from_select(element, compiler, **kw):
return "INSERT INTO %s (%s)" % (
compiler.process(element.table, asfrom=True),
compiler.process(element.select)
)
insert = InsertFromSelect(t1, select([t1]).where(t1.c.x>5))
print insert
生产:
"INSERT INTO mytable (SELECT mytable.x, mytable.y, mytable.z FROM mytable WHERE mytable.x > :x_1)"
现在,4 年后,该语法被合并到 SQLAlchemy 0.9 中,并向后移植到 0.8.3;您可以创建任何select(),然后使用Insert 对象的新from_select() 方法:
>>> from sqlalchemy.sql import table, column
>>> t1 = table('t1', column('a'), column('b'))
>>> t2 = table('t2', column('x'), column('y'))
>>> print(t1.insert().from_select(['a', 'b'], t2.select().where(t2.c.y == 5)))
INSERT INTO t1 (a, b) SELECT t2.x, t2.y
FROM t2
WHERE t2.y = :y_1
【讨论】:
str(),因为%s 已经这样做了。
select *,而只想select x, y(在许多列中),一种方法是from sqlalchemy import select,然后你可以使用这个select([t2,x, t2,y])而不是t2.select()。
从 0.8.3 开始,您现在可以直接在 sqlalchemy 中执行此操作:Insert.from_select:
sel = select([table1.c.a, table1.c.b]).where(table1.c.c > 5)
ins = table2.insert().from_select(['a', 'b'], sel)
【讨论】:
AttributeError: type object 'table2' has no attribute 'insert'
table2 是一个类,而不是 SQL 表达式的表对象。请参阅下面nosklo 的关于构造表对象的答案(在 Another EDIT 下)或按照此处的 SQLAlchemy 教程进行操作:docs.sqlalchemy.org/en/14/core/…
正如 Noslko 在评论中指出的那样,您现在可以摆脱原始 sql: http://www.sqlalchemy.org/docs/core/compiler.html#compiling-sub-elements-of-a-custom-expression-construct
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.sql.expression import Executable, ClauseElement
class InsertFromSelect(Executable, ClauseElement):
def __init__(self, table, select):
self.table = table
self.select = select
@compiles(InsertFromSelect)
def visit_insert_from_select(element, compiler, **kw):
return "INSERT INTO %s (%s)" % (
compiler.process(element.table, asfrom=True),
compiler.process(element.select)
)
insert = InsertFromSelect(t1, select([t1]).where(t1.c.x>5))
print insert
生产:
INSERT INTO mytable (SELECT mytable.x, mytable.y, mytable.z FROM mytable WHERE mytable.x > :x_1)
【讨论】:
Insert.from_select 方法!看我的回答。