如何实现双条件过滤下Excel数据向SQL表的增量写入?
Excel数据集写入SQL表的条件筛选需求
我有一份Excel格式的数据集需要写入SQL表,写入前需满足两个条件:
- 若整行数据已存在于SQL表中,则不写入该行;
- 若Step_API列的值已存在于SQL表的对应列中,且Source列值为'PIDM',也不写入该行。
我已通过SELECT EXCEPT实现第一个条件,现寻求第二个条件的实现方法,以下是已实现第一部分的代码:
# 将DataFrame写入临时表作为占位符 col_options = dict( dtype={ 'Step_ID': sqlalchemy.types.INTEGER(), 'Step_Level': sqlalchemy.types.VARCHAR(length=50), 'Step_API': sqlalchemy.types.VARCHAR(length=50), 'Source_ID': sqlalchemy.types.VARCHAR(length=150), 'Source_Well_Name': sqlalchemy.VARCHAR(length=150), 'Start_Date': sqlalchemy.types.Date(), 'Stop_Date': sqlalchemy.types.Date(), 'Source': sqlalchemy.types.VARCHAR(length=150), 'Created_By': sqlalchemy.types.VARCHAR(length=50), 'Created_Dt': sqlalchemy.types.Date(), 'Updated_By': sqlalchemy.types.VARCHAR(length=50), 'Updated_Dt': sqlalchemy.types.Date(), 'ETL_Load_Date': sqlalchemy.types.Date(), 'Comment':sqlalchemy.types.VARCHAR(length=150) } ) df.to_sql(name="obo_external_xref_temp", con=engine, schema= 'MDM', if_exists='replace', index=False, **col_options) # 筛选临时表与目标表之间的新记录(仅实现了第一个条件) query = """ SELECT Step_ID, Step_Level, Step_API, Source_ID, Source_Well_Name, Start_Date, Stop_Date, Source, Created_By, Created_Dt, Updated_By, Updated_Dt, ETL_Load_Date, Comment FROM MDM.obo_external_xref_temp EXCEPT SELECT Step_ID, Step_Level, Step_API, Source_ID, Source_Well_Name, Start_Date, Stop_Date, Source, Created_By, Created_Dt, Updated_By, Updated_Dt, ETL_Load_Date, Comment FROM MDM.obo_external_xref; """ new_entries = pd.read_sql(query, con=engine) # 将新记录追加到目标表 new_entries.to_sql(name="obo_external_xref", con=engine, schema= 'MDM', if_exists='append', index=False, **col_options)
第二个条件的实现方案
要满足第二个条件,需要在原有筛选逻辑基础上,额外排除那些**Step_API已存在于目标表且对应Source为'PIDM'**的记录。可以通过修改查询语句实现,以下是两种可行方式:
方式一:在EXCEPT结果后追加过滤
修改查询语句,先通过EXCEPT得到整行不存在的记录,再用NOT EXISTS子句排除符合第二个条件的记录:
query = """ SELECT * FROM ( SELECT Step_ID, Step_Level, Step_API, Source_ID, Source_Well_Name, Start_Date, Stop_Date, Source, Created_By, Created_Dt, Updated_By, Updated_Dt, ETL_Load_Date, Comment FROM MDM.obo_external_xref_temp EXCEPT SELECT Step_ID, Step_Level, Step_API, Source_ID, Source_Well_Name, Start_Date, Stop_Date, Source, Created_By, Created_Dt, Updated_By, Updated_Dt, ETL_Load_Date, Comment FROM MDM.obo_external_xref ) AS temp_new WHERE NOT EXISTS ( SELECT 1 FROM MDM.obo_external_xref t WHERE t.Step_API = temp_new.Step_API AND t.Source = 'PIDM' ); """
方式二:合并条件到同一查询
直接从临时表中筛选同时满足两个条件的记录,逻辑更紧凑:
query = """ SELECT Step_ID, Step_Level, Step_API, Source_ID, Source_Well_Name, Start_Date, Stop_Date, Source, Created_By, Created_Dt, Updated_By, Updated_Dt, ETL_Load_Date, Comment FROM MDM.obo_external_xref_temp temp WHERE -- 条件1:整行不存在于目标表 NOT EXISTS ( SELECT 1 FROM MDM.obo_external_xref t WHERE t.Step_ID = temp.Step_ID AND t.Step_Level = temp.Step_Level AND t.Step_API = temp.Step_API AND t.Source_ID = temp.Source_ID AND t.Source_Well_Name = temp.Source_Well_Name AND t.Start_Date = temp.Start_Date AND t.Stop_Date = temp.Stop_Date AND t.Source = temp.Source AND t.Created_By = temp.Created_By AND t.Created_Dt = temp.Created_Dt AND t.Updated_By = temp.Updated_By AND t.Updated_Dt = temp.Updated_Dt AND t.ETL_Load_Date = temp.ETL_Load_Date AND t.Comment = temp.Comment ) -- 条件2:Step_API未在目标表的PIDM来源中出现 AND NOT EXISTS ( SELECT 1 FROM MDM.obo_external_xref t WHERE t.Step_API = temp.Step_API AND t.Source = 'PIDM' ); """
替换原有query变量后,后续的pd.read_sql和to_sql步骤保持不变即可。
内容的提问来源于stack exchange,提问作者Yamila Orrego
相关产品推荐
相关产品推荐

