如何使用SQLAlchemy将查询表达式中的SQL文件转储到批量插入到DBMS中?

Mah*_*der 12 python performance orm bulkinsert sqlalchemy

当我解释问题时,请耐心等待我,我是如何解决这个问题的,最后我的问题是如何改进它.

我有一个来自离线批处理作业的100,000行csv文件,我需要将其作为正确的模型插入到数据库中.通常,如果这是一个相当直接的加载,只需将CSV文件重新设置为适合模式即可轻松加载; 但是,我不得不做一些需要查询的外部处理,使用SQLAlchemy生成我想要的数据会更方便.

我想要的数据是3个模型,它们代表数据库中3个预先存在的表,每个后续模型都依赖于以前的模型.例如:

Model C --> Foreign Key --> Model B --> Foreign Key --> Model A
Run Code Online (Sandbox Code Playgroud)

因此,模型必须按照A,B和C的顺序插入.我想出了一个生产者/消费者的方法:

 - instantiate a multiprocessing.Process which contains a
 threadpool of 50 persister threads that have a threadlocal 
 connection to a database

 - read a line from the file using the csv DictReader

 - enqueue the dictionary to the process, where each thread creates
 the appropriate models by querying the right values and each
 thread persists the models in the appropriate order
Run Code Online (Sandbox Code Playgroud)

这比非线程读取/持久化更快,但它比将文件批量加载到数据库中要慢.大约45分钟后,工作完成了.为了好玩,我决定用SQL语句编写它,花了5分钟.

但是编写SQL语句花了我几个小时.所以我的问题是,我可以使用更快的方法使用SQLAlchemy插入行吗?据我了解,SQLAlchemy不是为批量插入操作而设计的,所以这不太理想.

这是我的问题,有没有办法使用SQLAlchemy生成SQL语句,将它们放在一个文件中,然后只是使用批量加载到数据库中?我知道str(model_object),但它没有显示插值.

如果能更快地完成这项工作,我将不胜感激.

谢谢!

Mar*_*nas 2

首先,除非您实际上拥有一台具有 50 个 CPU 核心的机器,否则使用 50 个线程/进程不会提高性能 - 它实际上会使速度变慢。

其次,我有一种感觉,如果你使用 SQLAlchemy 的方式一次插入多个值,它会比创建 ORM 对象并逐一保存它们要快得多。