【问题标题】:Reading and writing large volume of data in Python在 Python 中读取和写入大量数据
【发布时间】:2017-11-26 03:56:48
【问题描述】:

我正在尝试从数据库中检索大量数据(超过 700 万条)并尝试保存一个平面文件。正在使用 python 代码(python 调用存储过程)检索数据。但是我在这里遇到了问题。该进程正在消耗大量内存,因此由 unix 机器自动终止该进程。我正在使用 read_sql_query 读取数据并使用 to_csv 写入平面文件。所以,我想问问有没有办法解决这个问题。可能一次只读取几千行并将它们保存并转到下一行。 我什至也使用了 chunksize 参数。但这似乎并没有解决问题。

任何帮助或建议将不胜感激。

【问题讨论】:

  • 您使用的是什么关系型数据库?大多数都有 CSV 方法。

标签: python sql pandas


【解决方案1】:

Pandas 数据框很棒,如果数据是时间序列和/或需要修改,我会按照@PaSTE 的建议使用read_sql_query()

但是,如果您决定简单地从数据库中读取数据并将数据立即处理成另一种格式,并且您对使用一些 Python 原语感到满意,那么我会简单地利用“原始”内置 DB-API(相同的 API Pandas 正在使用)并像这样逐行读取:

import MySQLdb

db = MySQLdb.connect(host='hostname', user='john', passwd='doe', db='penguins')
cursor = db.cursor()

cursor.execute(f"SELECT * FROM your_table;")

for row in cursor:
    print(row)

或者使用这样的块:

import MySQLdb

db = MySQLdb.connect(host='hostname', user='john', passwd='doe', db='penguins')
cursor = db.cursor()

cursor.execute("SELECT COUNT(*) FROM your_table")
row_count = cursor.fetchone()[0]
chunk_size = 1000

for offset in range(0, row_count, chunk_size):
    cursor.execute(f"SELECT * FROM your_table LIMIT {chunk_size} OFFSET {offset};")

    for row in cursor:
        print(row)

这不是特定于驱动程序的,我知道的所有驱动程序都可以,因此请使用您喜欢的任何一个。

享受吧!

【讨论】:

    【解决方案2】:

    当您在read_sql_query 中使用chunksize 时,您可以迭代结果以避免一次将所有内容加载到内存中。但是,您还必须以块的形式写入 CSV 文件,以确保您不只是将查询结果逐块复制到一个新的、巨大的 DataFrame 块中。注意只写一次列标题。以下是使用 pandas 的示例:

    import pandas as pd
    
    dbcon = ... # whatever
    
    with open("out.csv", "w") as fh:
        chunks = pd.read_sql_query("SELECT * FROM table_name", dbcon, chunksize=10000)
        next(chunks).to_csv(fh, index=False)  # write the first chunk with the column names,
                                              # but ignore the index (which will be screwed up anyway due to the chunking)
        for chunk in chunks:
            chunk.to_csv(fh, index=False, header=False) # skip the column names from now on
    

    如果您在对read_sql_query 的调用中明确设置index_col,则在写入CSV 时不必忽略索引。

    【讨论】:

    • 非常感谢。这正是我想要的。感谢您的帮助。
    【解决方案3】:

    与其使用 pandas 库,不如直接建立数据库连接(使用 psycopg2、pymysql、pyodbc 或其他适当的连接器库)并使用 Python 的 db-api 以一对一或可以处理任何大小的块。

    【讨论】:

      猜你喜欢
      • 2013-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-29
      • 1970-01-01
      相关资源
      最近更新 更多