【问题标题】:Multiprocessing loading of data and committing to sqlalchemy多处理数据加载并提交到 sqlalchemy
【发布时间】:2015-05-01 12:43:22
【问题描述】:

我正在从文件中加载数据。我有很多文件,所以我有几个进程加载文件列表:

 with concurrent.futures.ProcessPoolExecutor(max_workers=4) as executor:
    for x, y, z in executor.map(load_my_file, path_list):

加载我的文件:加载数据,将“USERS”和“POSTS”存储在两个字典中并返回,合并到一个字典中,分别用于用户和帖子,然后我批量提交它们。

每个用户可能有很多帖子,但在文件中每条记录只是一个帖子和一个用户一起。所以这就是字典背后的原因,所以我在使用 sqlalchemy 插入时没有主键重复。

但是,这会占用大量内存。我有大约 160 万条记录,60 万用户,而我的 python 程序正在使用大量内存(超过我的 16gb 内存允许的内存)。

我研究过使用 session.merge,但似乎每次调用它时都会查询数据库,这使得该过程非常缓慢。有没有其他方法可以解决这个问题? 我希望能够在每个进程中进行提交,而不是在最后将它们全部合并到一个大字典中,但我不想破坏任何关系或出现主键错误。

【问题讨论】:

  • 为什么会有并发的要求?它真的有任何优势吗?您必须加载多少文件?这是从远程主机加载的吗?
  • 它提供了巨大的速度优势。约 80 个文件。本地加载。

标签: python mysql python-3.x dictionary sqlalchemy


【解决方案1】:

并行加载 80 个本地文件比一次加载一个要快得多,这很奇怪。不过,我可能会提出一些理由。

但是,好的。您可以按原样将数据导入临时非规范化表。之后,使用 SQL 查询将数据复制到目标规范化表。然后删除临时表(或者如果您需要定期截断)。另外,看看你的 SQLAlchemy 查询:不仅merge 会降低性能。实际上,通过 add_all 进行的“大规模”插入不会变成单个插入。您将使用带有字典列表的insert 查询:I’m inserting 400,000 rows with the ORM and it’s really slow!

我研究过使用 session.merge,但每次调用它似乎都会查询数据库

情况更糟。它应该检查记录是否存在(第一个查询),然后插入或更新记录(第二个查询)。因此,将其用于处理大型数据数组似乎是有问题的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-07
    • 2012-01-24
    • 1970-01-01
    • 2013-12-20
    • 2018-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多