我正在寻找SQLAlchemy中的一种方法来执行批量INSERT
,其行是查询的结果。我知道会话有函数add
可用于添加单个对象,但我似乎无法找到它如何与子查询一起工作。
我知道我可以单独迭代子查询的结果和add
它们,但这似乎有些低效。就我而言,我正在处理可能需要插入的大量数据。
答案 0 :(得分:2)
我看到以下选项:
我会建议选项1)或3) 事实上,如果你没有任何对象验证并且你只使用一个RDBMS,我会坚持选项 3)。
答案 1 :(得分:0)
我相信在SQLAlchemy中执行此操作的唯一方法是使用Session.execute发出原始SQL语句
答案 2 :(得分:0)
由于这是该常见问题在Google上的最高结果,并且实际上有更好的解决方案可用,因此这里是更新的答案。您可以使用Insert.from_select()
方法。尽管很难找到,但记录在案here。
使用Table对象时,您可以使用类似以下内容的方法:
>>> from sqlalchemy.sql import select
>>> stmt = TargetTable.insert().from_select([TargetTable.c.user_id, TargetTable.c.user_name],
select([SrcTable.c.user_id, SrcTable.c.user_name]))
>>> print(stmt)
INSERT INTO "TargetTable" (user_id, user_name) SELECT "SrcTable".user_id, "SrcTable".user_name
FROM "SrcTable"
最后用engine.execute(stmt)
等执行。
最终输出语句由SQLAlchemy编译,具体取决于引擎中使用的方言。在这里,我使用了SQLite语言。
这成功地避免了将任何数据加载到python对象中,让数据库引擎有效地处理了所有事情。 万岁!
与在text()
中使用文本sql语句相反,该方法也是RDBMS独立的,因为它仍然使用here中所述的SQLAlchemy表达式语言。这种语言可以确保在执行时编译为正确的方言。
最初的问题指向一个用例,其中ORM用于与数据库进行交互。您可能也使用ORM基础定义了表。存储在这些对象中的元数据现在的工作方式略有不同。因此,我们将对示例进行一些修改:
>>> from sqlalchemy.sql import select, insert
>>> stmt = insert(TargetTable).from_select([TargetTable.user_id, TargetTable.user_name],
select([SrcTable.user_id, SrcTable.user_name]))
>>> engine.execute(stmt)
INFO sqlalchemy.engine.base.Engine INSERT INTO "TargetTable" (user_id, user_name) SELECT "SrcTable".user_id, "SrcTable".user_name
FROM "SrcTable"
好吧。实际上,它甚至使它变得更简单。
这将很多更快。
P.S。这是文档中的另一个秘密。是否想以相同的动态方式使用sql WITH
语句? You can do it with "CTE's"