我有一个循环文件夹并在每个文件夹中的Python脚本,对我们的Redshift集群执行sql文件(使用psycopg2)。以下是执行循环的代码(注意:这对于只需几分钟执行的查询就可以正常工作):
for folder in dir_list:
#Each query is stored in a folder by group, so we have to go through each folder and then each file in that folder
file_list = os.listdir(source_dir_wkly + "\\" + str(folder))
for f in file_list:
src_filename = source_dir_wkly + "\\" + str(folder) + "\\" + str(f)
dest_filename = dest_dir_wkly + "\\" + os.path.splitext(os.path.basename(src_filename))[0] + ".csv"
result = dal.execute_query(src_filename)
result.to_csv(path_or_buf=dest_filename,index=False)
execute_query是存储在另一个文件中的方法:
def execute_query(self, source_path):
conn_rs = psycopg2.connect(self.conn_string)
cursor = conn_rs.cursor(cursor_factory=psycopg2.extras.RealDictCursor)
sql_file = self.read_sql_file(source_path)
cursor.execute(sql_file)
records = cursor.fetchall()
conn_rs.commit()
return pd.DataFrame(data=records)
def read_sql_file(self, path):
sql_path = path
f = open(sql_path, 'r')
return f.read()
我有几个查询需要大约15分钟才能执行(考虑到我们的Redshift集群中的数据大小,这并不罕见),并且它们在SQL Workbench中执行得很好。我可以在AWS控制台中看到查询已完成,但脚本只是挂起并且不会将结果转储到csv文件,也不会继续执行文件夹中的下一个文件。
我没有指定任何超时。还有什么我想念的吗?
答案 0 :(得分:0)
行records = cursor.fetchall()
可能是罪魁祸首。它读取所有数据,因此将查询中的所有结果加载到内存中。鉴于您的查询非常大,可能无法将这些数据全部加载到内存中。
你应该迭代光标的结果并逐个写入你的csv。通常,尝试一次从数据库查询中读取所有数据并不是一个好主意。
您需要重构代码才能这样做:
for record in cursor:
csv_fh.write(record)
其中csv_fh
是csv文件的文件句柄。您对pd.DataFrame
的使用将需要重写,因为它看起来希望将所有数据传递给它。