在Python中读取和写入大量数据

时间:2017-06-22 18:15:43

标签: python sql pandas

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

非常感谢任何帮助或建议。

3 个答案:

答案 0 :(得分:2)

chunksize中使用read_sql_query时,您可以迭代结果以避免一次将所有内容加载到内存中。但是,您还必须以块的形式写出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

如果您在index_col的调用中明确设置read_sql_query,则在编写CSV时无需忽略索引。

答案 1 :(得分:0)

不是使用pandas库,而是直接建立数据库连接(使用psycopg2,pymysql,pyodbc或其他适当的连接器库)并使用Python的db-api同时读取和写入行,你可以处理的一个或一个大小的块。

答案 2 :(得分:0)

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)

这不是特定于驱动程序的,并且对于我所知道的所有驱动程序都是可能的,因此请使用您喜欢的驱动程序。

享受!