我有一个庞大的表(约8亿),我需要根据某些段条件获取数据。
数据:
d_id month_id sec average Class
89 201701 S 5.98 A
73 201703 N 7.63 B
31 201708 F 6.38 P
11 201709 K 6.38 P
我有两个清单:
monthList = [201701,201702,201703]
所以sql查询是:
sql_query = str("""select * from dbo.table_name where month_id IN monthList;""")
现在我想在服务器端游标中保存这些数据,并从该获取基于classList的子集
curs = cnxn.cursor('Class')
classList = ['A','B','P']
while True:
records = curs.fetchmany(int(1e3))
if not records:
break
for record in records:
# here I want to use the classList to subset the data , something like
df = pd.DataFrame()
df.append(curs.fetchmany([cursor['Class'] == classList]))
# And once all the records of each Class has been read create csv
df.to_csv("ClassList.csv")
所以对于上面给出的数据: 将生成3个csv: 1. ClassA.csv
d_id month_id sec average Class
31 201708 F 6.38 P
11 201709 K 6.38 P
所有数据都在PostgreSQL中,我使用psycopg2调用
有人可以帮助我: 这甚至可以用于服务器端游标。 2.我基本上需要根据作为列表给出的month_id,从所有数据创建每个类的组合csv。
答案 0 :(得分:3)
这不是服务器端游标的工作方式 - 它们使服务器保持状态 客户端遍历结果集,可能是批量提取 扭转遍历。好处是服务器维护状态 关于连接,以便客户端可以更有效地分配内存 (默认情况下,客户端会在允许您的代码之前尝试获取所有内容 重复。对于80亿行,这可能会导致问题。)
但要记住的关键是确定光标返回的数据 通过查询 - 您可以比较每行的结果来决定做什么, 但是你仍在逐行操作,而不是改变返回的结果 服务器。但是......如果你滥用,你的DBA可能会以暴力意图来追捕你 服务器...持有80亿行的服务器端游标,同时进行多次遍历会对数据库造成很多的内存压力,从而减慢了其他用户的负担。
通过Pandas对本地系统内存也是如此 - 基于您的示例,除了使用它生成CSV之外,您实际上并没有做任何其他事情。
怎么办?
如果您只需要编写一个大的组合CSV,使用psycopg2的本机copy_expert
功能直接流式传输到CSV,与服务器端游标结合使用。
我经常使用这种方法从大型数据集创建CSV 保持数据库和客户端内存不变。它也更快 我可以用直接的Python编写任何逐行的CSV生成。
最后,您不清楚需要1个CSV或3个CSV。你的最终评论 引用“组合CSV”,所以要做到这一点,建立在迈克尔的评论, 尝试这样的事情:
sql = '''
copy (
select *
from your_table_name
where month_id in (. . .)
and Class in (. . .)
)
to stdout
with (
format csv, header
)'''
stmt = db.cursor('my_cursor')
with open('output.csv', 'w') as outfile:
stmt.copy_expert(sql, outfile)
如果确实需要3个单独的CSV,则可以修改方法以执行3个 单独的通行证
希望有所帮助。
见