我正在尝试从数据库中检索大量数据(超过700万)并尝试保存平面文件。使用python代码(python调用存储过程)检索数据。但我在这里遇到了问题。这个过程耗费了大量内存,因此unix机器会自动终止进程。我使用read_sql_query读取数据,使用to_csv写入平面文件。所以,我想问一下是否有办法解决这个问题。可能一次只读几千行并保存它们并转到下一行。 我甚至也使用了chunksize参数。但它似乎没有解决问题。
非常感谢任何帮助或建议。
答案 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)
这不是特定于驱动程序的,并且对于我所知道的所有驱动程序都是可能的,因此请使用您喜欢的驱动程序。
享受!