使用psycopg2.copy_* 方法之一是可行的方法。取决于哪一个 -
- csv 是否有标题?
- csv 结构是否与表完全匹配(列的数量和类型)?
注意 #1 - 采用路径的复制命令形式要求该路径存在于数据库服务器上。在 Heroku 中,情况永远不会如此。相反,您需要这样的命令形式:copy table_name from stdin...。 copy_from 方法是该表单的便捷方法。
1) 最简单的情况 - 逗号分隔的文件,没有与表结构完全匹配的标题:
stmt.copy_from(request.files['data_file'], 'your_table', sep=',')
(stmt 是一个游标,最好在with conn.cursor() as stmt: 子句中使用)
2) 没有标题,但 csv 只有列的子集:
stmt.copy_from(request.files['data_file'], 'some_table', sep=',', cols=['col1', 'col2', 'col3'])
3) 如果你有一个标题,你需要copy_expert -
sql = """
copy some_table (col1, col2, col3)
from stdin with csv header delimiter ','
"""
stmt.copy_expert(sql, request.files['data_file'])
注意 #2 - 数据将被隐式转换为正确的类型。它还需要满足数据约束。单个记录的任一操作失败都会终止整个事务。因此,您可能需要花点时间将所有数据加载到一个简单的临时表中,清理它,然后执行select into (
注意#3 - 我猜你可以直接使用request.files,但没有测试它。如果失败,将数据流式传输到临时文件并将其用作复制方法的参数。
见: