我正在尝试使用 COPY 命令将 2800 个 CSV 加载到 RDS Postgres 中。我下面的程序大致基于 this,它所做的是 (1) 列出所有 S3 对象 (2) 在 Postgres 中创建一个表 (3) 尝试将一个文件复制到我作为 POC 创建的表中。
import boto3
import psycopg2
S3_BUCKET = "arapbi"
S3_FOLDER = "polygon/tickers/"
s3 = boto3.resource("s3")
my_bucket = s3.Bucket(S3_BUCKET)
object_list = []
for obj in my_bucket.objects.filter(Prefix=S3_FOLDER):
object_list.append(obj)
conn_string = "postgresql://user:[email protected]:5432/arapbi"
def write_sql(file):
sql = f"""
COPY tickers
FROM '{file}'
DELIMITER ',' CSV;
"""
return sql
table_create_sql = """
CREATE TABLE IF NOT EXISTS public.tickers ( ticker varchar(20),
timestamp timestamp,
open double precision,
close double precision,
volume_weighted_average_price double precision,
volume double precision,
transactions double precision,
date date
)"""
# Create the table
pg_conn = psycopg2.connect(conn_string, database="arapbi")
cur = pg_conn.cursor()
cur.execute(table_create_sql)
pg_conn.commit()
cur.close()
pg_conn.close()
# attempt to upload one file to the table
sql_copy = write_sql(object_list[-1].key)
pg_conn = psycopg2.connect(conn_string, database="arapbi")
cur = pg_conn.cursor()
cur.execute()
pg_conn.commit()
cur.close()
pg_conn.close()
sql_copy
,在这种情况下,是
COPY tickers
FROM 'polygon/tickers/dt=2023-04-24/2023-04-24.csv'
DELIMITER ',' CSV;
当我运行应该将文件复制到 Postgres 的部分时,出现以下错误:
FeatureNotSupported: COPY from a file is not supported
HINT: Anyone can COPY to stdout or from stdin. psql's \copy command also works for anyone.
我在网上可以找到的唯一其他示例是FeatureNotSupported:不支持从文件中复制,该问题没有得到解决。
我仍在研究这个问题,如果我先到达那里,我会更新答案。我很好奇是否其他人有像我这样的工作量(需要将 csv 从 S3 复制到 RDS Postgres)以及他们如何解决它。
postgres
COPY
命令依赖于服务器可访问的文件。通常这意味着文件位于服务器本身上,因此对文件进行远程 COPY 不起作用。 RDS无法访问S3文件路径,因此复制命令不起作用(事实上我怀疑它在RDS上被禁用)。仍然支持从 STDIN 复制,如错误消息所示:
HINT: Anyone can COPY to stdout or from stdin.
https://www.postgresql.org/docs/current/sql-copy.html
正如 @adrian klaver 的评论中提到的,psycopg 有一些用于复制的复制辅助函数 -
copy_from
和 copy_expert
都采用类似文件的对象(例如 CSV)作为参数。