[英]Copy command doesnt update the Id_sequence column when copying from csv throws error to null value in column "id" violates not-null constraint
我有 csv 文件,必須將數據復制到 postgre 表,如果在我的 csv 中,如果我不輸入 Id 和 Updated_at 的數據會拋出錯誤,但它不應該因為 id 被標記為默認值和增量。 我正在從 python 做這個副本
錯誤:
2019-12-01T14:05:16.57+0530 [APP/PROC/WEB/0] OUT 錯誤代碼:23502。錯誤錯誤:“id”列中的空值違反了非空約束 2019-12-01T14:05:16.57 +0530 [APP/PROC/WEB/0] OUT DETAIL:失敗的行包含(null,street_address,null)。
2019-12-01T14:05:16.57+0530 [APP/PROC/WEB/0] OUT CONTEXT:復制人口統計類型,第2行:“,街道地址,”
CREATE TABLE IF NOT EXISTS public.demographic_types (
id bigint DEFAULT nextval('public.demographic_types_id_seq'::regclass) NOT NULL,
demographic_type text NOT NULL,
updated_at timestamp with time zone DEFAULT now() NOT NULL
);
Python代碼
def load_data(conn):
"""
Load seeded data
"""
db = os.environ['DATABASE_URL']
dbname = db.replace("hsdp_pg","harbinger")
try:
with psycopg2.connect(dbname) as conn1:
#migrate_db(conn, dbname, mirth_pw, harbinger_pw, psql_path, init_db)
conn1.commit()
except psycopg2.Error as exp1:
print(exp1)
print ('Error Code: %s. Error %s' % (exp1.pgcode, exp1.pgerror))
print(conn1)
path = os.path.dirname(os.path.realpath(__file__))
print (os.path.join(path,"database/data/*.csv"))
for fle in sorted(glob.glob(os.path.join(path,"database/data/*.csv"))):
print ('>>>Migrating data %s' % fle)
table_name = os.path.basename(fle).replace('.csv', '')
try:
#silent_query(conn, sql, None)
with conn1.cursor() as cur:
#delete data first
print('Deleting data from table %s' % table_name)
cur.execute('TRUNCATE %s CASCADE' % table_name)
print('i am done and waiting')
conn1.commit()
with open(fle, 'r') as f:
#headers = ", ".join(table_column_mapping_data[table_name])
print("i am here ")
#cur.copy_from(f, table_name, sep=',')
#sql = "INSERT INTO %s (ID, demographic_type, updated_at) VALUES (%s,%s,%s)" % table_name
#record_insert = ('1', 'phone', '')
#cur.execute(sql, record_insert)
sql = "COPY %s from STDIN WITH CSV HEADER DELIMITER ','" % table_name
#print(sql)
cur.copy_expert(sql, f)
conn1.commit()
except psycopg2.Error as exp2:
print ('Error Code: %s. Error %s' % (exp2.pgcode, exp2.pgerror))
如果我理解正確,您想從 CSV 文件導入一些數據,但允許數據庫自動填充一些具有默認值的列(id 列的序列的 nextval 或 updated_at 列的 now() )。
為此,您必須告訴復制命令哪些列在 CSV 文件中,如下所示:
for fle in sorted(pathlib.path(path,"database/data/").glob("*.csv")):
logging.info('>>>Migrating data %s', fle)
table_name = fle.stem
try:
with conn1.cursor() as cur:
logging.info('Deleting data from table %s', psycopg2.extensions.quote_ident(table_name))
cur.execute('TRUNCATE %s CASCADE' % psycopg2.extensions.quote_ident(table_name, cur))
logging.info('i am done and waiting')
with open(fle, 'r') as f:
cur.copy_from(
f,
table_name,
sep=',',
columns=[
'demographic_type',
'updated_at',
'street_address',
'city',
'state_or_province',
'postal_code',
'secondary_phone',
# more columns, but without id or created_at
]
)
conn1.commit()
except psycopg2.Error as exp2:
print ('Error Code: %s. Error %s' % (exp2.pgcode, exp2.pgerror))
一點解釋。 您面臨的主要問題來自對默認規范實際作用的誤解。 期望提供默認值意味着使用此值而不是 null會出現此問題。 情況並非如此,如果列列表中未提及列名稱,則在插入時指定默認值使用此值。 因此給出以下內容:
create table use_default ( id serial primary key
, column1 text
, column2 text default 'Undefined'
) ;
insert into use_default(column1) values('abc');
-- gives the default to column2 as it is NOT mentioned in the insert
select * from use_default;
/* results in
id column1 column2
1 abc Undefined
*/
insert into use_default(column1, column2)
values ('def','given value')
, ('ghi', null) ;
-- gives row def with column2 as 'given value' as it is specified
-- but row ghi has column2 as NULL. again as it was specified value
select * from use_default;
/*
id column1 column2
1 abc Undefined
2 def given value
3 ghi
*/
到目前為止,每個插入都生成了未指定的 id。 但僅僅因為它被指定為自動生成(由於串行定義在邏輯上最少),如果提供它,它仍然具有相同的處理。 注意有時不幸的是,NULL 是一個非常好的值。 所以:
insert into use_default(id, column1) values (0,'Special id');
Works just fine and gives the id as specified;
select * from use_default where id = 0;
/*
id column1 column2
0 Special id Undefined
*/
insert into use_default(id, column1) values(null, 'Special2');
/*
ERROR: null value in column "id" violates not-null constraint
DETAIL: Failing row contains (null, Special2, Undefined).
*/
現在您不會編寫試圖將 PK 設置為 null 的語句,但這本質上是 copy 命令正在執行的操作。 由於您沒有指定列,它嘗試使用 NULL 填充所有列而不是省略某些列。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.