SQL Alchemy - INSERT查询结果

时间:2011-08-15 17:48:37

标签: sqlalchemy bulkinsert

我正在寻找SQLAlchemy中的一种方法来执行批量INSERT,其行是查询的结果。我知道会话有函数add可用于添加单个对象,但我似乎无法找到它如何与子查询一起工作。

我知道我可以单独迭代子查询的结果和add它们,但这似乎有些低效。就我而言,我正在处理可能需要插入的大量数据。

3 个答案:

答案 0 :(得分:2)

我看到以下选项:

  1. 使用SA模型:使用从数据库加载的数据创建基础对象,将它们添加到会话和提交。
    • 优点:如果您有任何AS模型级别验证,您可以使用它;如果模型对象映射到多个表(Joined-Table Inheritance),也可以插入多个表; 独立于RDBMS
    • 缺点:最贵
  2. 使用Insert语句:将数据库中的数据加载到python中并使用Insert Expressions执行
  3. 仅使用RDBMS 创建数据:使用RDBMS批量插入仅绕过SA和python。
    • 优点:最快
    • 缺点:未执行业务对象验证;可能需要特定于RDBMS的实施
  4. 我会建议选项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用于与数据库进行交互。您可能也使用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"