您将获得一个 iterator 数据帧,而不是单个数据帧(生成器是一种迭代器),因为您指定了 chunksize 值。见pandas.read_sql() documentation:
chunksize : int,默认无
如果指定,则返回一个迭代器,其中 chunksize 是要包含在每个块中的行数。
你需要遍历那个迭代器;最简单的方法是使用for 循环。然后在写出 CSV 文件时不想再次使用分块。您应该改为以 append 模式打开输出文件,以便将每个块作为新行添加到文件中:
chunks = pd.read_sql('My QUERY', con=conn, chunksize=10000)
for chunk in chunks: # each chunk is a dataframe
# append the data from each chunk to the same output file
chunk.to_csv("test.csv", sep=",", mode="a")
然而,这并不是从表中生成 CSV 文件的有效方法!如果您使用 Oracle SQL*Plus 命令行工具,您将更有效地获取 CSV 文件,请参阅 Oracle 自己的博客文章 Fast Generation of CSV and JSON from Oracle Database。
即使只是将 SQLAlchemy 查询直接流式传输到 csv.writer() 对象会更好:
import cx_Oracle
import csv
from sqlalchemy import create_engine
DATABASE = "MY database"
SCHEMA = "MY USER"
PASSWORD = "MY PASS"
BATCHSIZE = 10000
connstr = "oracle://{}:{}@{}".format(SCHEMA, PASSWORD, DATABASE)
engine = sqlalchemy.create_engine(connstr, arraysize=BATCHSIZE)
conn = engine.connect()
with open("test.csv", "w") as outputfile:
writer = csv.writer(outputfile)
results = conn.execute('My QUERY')
writer.writerows(results)
然后cx_Oracle 库会为您将结果从数据库批量流式传输到 Python,然后writer.writerows() 会将这些结果写入您的 CSV 文件。批处理大小由arraysize 参数控制,该参数指示cx_Oracle 库在服务器和客户端之间的每次往返中加载那么多行。如果您必须使用 DataFrames,您可能也想在 Panda 的代码中设置它。
你也不需要 SQLAlchemy,真的;你可以直接在这里使用 cx_Oracle,并设置cursor.arraysize parameter:
import cx_Oracle
import csv
DATABASE = "MY database"
SCHEMA = "MY USER"
PASSWORD = "MY PASS"
BATCHSIZE = 10000
conn = cx_Oracle.connect(user=SCHEMA, password=PASSWORD, dsn=DATABASE)
cursor = connection.cursor()
cursor.arraysize = BATCHSIZE
with open("test.csv", "w") as outputfile:
writer = csv.writer(outputfile)
results = cursor.execute('My QUERY')
writer.writerows(results)