如何向包含两个外键的SQL表插入CSV导入的数据?
问题原因
- 直接报错:
event表设计中没有patient_name字段,插入语句中指定了不存在的字段触发报错 - 逻辑错误:三个表是关联关系,
event表仅存储关联外键,不直接存患者名称、事件类型名称这类冗余字段,不能直接把CSV行插入到event表 - 隐藏问题:当前CSV读取配置不对,每个字段前后都带有多余的双引号需要清理,同时你原来的插入语句中CSV列和数据库字段的对应关系也写错了
解决步骤
- 修正CSV读取逻辑,清理字段多余引号,跳过首行表头
- 遍历每行数据时,先校验
patient表:如果当前患者ID不存在则插入,存在则直接取患者ID作为event表的外键 - 再校验
event_type表:如果当前事件类型(HR/RR)不存在则插入,存在则直接取类型ID作为event表的外键 - 拿到两个外键ID后,再组装事件的其他字段插入到
event表 - 所有操作完成后提交事务,避免数据丢失
完整实现代码
import psycopg2 import csv # 数据库连接 conn = psycopg2.connect(host='localhost', dbname='patientdb',user='username',password='password',port='') cur = conn.cursor() try: with open(r'/Users/williaml/Downloads/events.csv') as csvfile: spamreader = csv.reader(csvfile, delimiter=',', quotechar=' ') # 跳过表头行 next(spamreader) for row in spamreader: # 清理每个字段前后的多余引号 patient_id = row[0].strip('"') patient_name = row[1].strip('"') event_type_name = row[2].strip('"') event_value = row[3].strip('"') event_unit = row[4].strip('"') event_time = row[5].strip('"') # 处理患者表:不存在则插入 cur.execute("SELECT patient_id FROM patient WHERE patient_id = %s", (patient_id,)) if not cur.fetchone(): cur.execute("INSERT INTO patient (patient_id, patient_name) VALUES (%s, %s)", (patient_id, patient_name)) # 处理事件类型表:不存在则插入 cur.execute("SELECT id FROM event_type WHERE name = %s", (event_type_name,)) type_res = cur.fetchone() if not type_res: cur.execute("INSERT INTO event_type (name) VALUES (%s) RETURNING id", (event_type_name,)) event_type_id = cur.fetchone()[0] else: event_type_id = type_res[0] # 插入事件表 cur.execute(""" INSERT INTO event (event_type, event_unit, event_value, event_time, patient) VALUES (%s, %s, %s, %s, %s) """, (event_type_id, event_unit, event_value, event_time, patient_id)) # 提交所有操作 conn.commit() print("数据导入完成") except Exception as e: # 出错回滚 conn.rollback() print(f"导入出错:{e}") finally: cur.close() conn.close()
内容的提问来源于stack exchange,提问作者William
相关产品推荐
相关产品推荐

