在源和目标上使用具有不同列数的Python copy_from

时间:2019-01-11 16:27:03

标签: python postgresql etl psycopg2

我正在尝试使用Python从CSV源到PostgreSQL数据库的新ETL流程。

我已经为目的地创建了表格。但是,我的数据库表上有create_at列,默认值为CURRENT_DATE。另一方面,我在CSV文件上没有create_at列。

数据库中的WP_SALES表包含:

id (int) PK
order_date (timestamp)
order_status (character varying)
customer_id (smallint)
product (character varying)
product_category (character varying)
quantity (smallint)
total_price (money)
create_at (date) DEFAULT CURRENT_DATE

在CSV上,它包含:

id 
order_date 
order_status 
customer_id 
product 
product_category 
quantity 
total_price

这是我尝试的代码:

import psycopg2
conn = psycopg2.connect ("host=localhost dbname=postgres user=postgres  port=5432")
cur = conn.cursor()
with open('[Technical Test - Data Engineer] Sale Report - wp.csv', 'r') as source:
    next(source)
    cur.copy_from(source, 'public."WP_SALES"', sep=',')

conn.commit()

我希望输出将是加载到表中的CSV上的所有数据,created_at列将填充其默认值(CURRENT_DATE)。

我得到的是这个错误:

Traceback (most recent call last):
  File "D:\Warung Pintar\TESTQuery", line 8, in <module>
  cur.copy_from(source, 'public."WP_SALES"', sep=',')
psycopg2.DataError: missing data for column "create_at"
CONTEXT:  COPY WP_SALES, line 1:     "127530,2018-10-20T03:41:14,sale,1645,ABC001,Minuman Sachet,2,19400"

[Finished in 0.2s]

我希望在不调整CSV文件的情况下解决该问题。

谢谢。

1 个答案:

答案 0 :(得分:0)

如psycopg2 documentation中所述,copy_from()具有用于列的命名参数

  

列-可以使用要导入的列名进行迭代。长度和类型应与要读取的文件内容相匹配。如果未指定,则假定整个表与文件结构匹配。

所以以下应该是您所需要的

cur.copy_from(source, 'public."WP_SALES"', sep=',', columns=['id', 'order_date', 'order_status', 'customer_id', 'product', 'product_category', 'quantity', 'total_price'])