即使在查询完成后,Python脚本在执行长时间运行的查询时也会挂起

时间:2014-11-05 15:19:41

标签: python postgresql amazon-redshift

我有一个循环文件​​夹并在每个文件夹中的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文件,也不会继续执行文件夹中的下一个文件。

我没有指定任何超时。还有什么我想念的吗?

1 个答案:

答案 0 :(得分:0)

records = cursor.fetchall()可能是罪魁祸首。它读取所有数据,因此将查询中的所有结果加载到内存中。鉴于您的查询非常大,可能无法将这些数据全部加载到内存中。

你应该迭代光标的结果并逐个写入你的csv。通常,尝试一次从数据库查询中读取所有数据并不是一个好主意。

您需要重构代码才能这样做:

for record in cursor:
    csv_fh.write(record)

其中csv_fh是csv文件的文件句柄。您对pd.DataFrame的使用将需要重写,因为它看起来希望将所有数据传递给它。