有两种选择:
- 使用
MERGE
语句代替INSERT ... ON CONFLICT
。 - 使用
UPDATe
带a的语句JOIN
,后跟条件语句INSERT
。
MERGE的T-SQL文档说:
性能提示:当两个表具有匹配特征的复杂混合时,为MERGE语句描述的条件行为最有效。例如,如果不存在则插入行,或者如果匹配则更新行。当仅基于另一个表的行更新一个表时,可使用基本的INSERT,UPDATE和DELETE语句提高性能和可伸缩性。
在许多情况下,仅使用分隔符
UPDATE和
INSERT语句会更快,更简单。
engine = sa.create_engine( connection_uri, fast_executemany=True, isolation_level="SERIALIZABLE")with engine.begin() as conn: # step 0.0 - create test environment conn.execute(sa.text("DROP TABLE IF EXISTS main_table")) conn.execute( sa.text( "CREATE TABLE main_table (id int primary key, txt varchar(50))" ) ) conn.execute( sa.text( "INSERT INTO main_table (id, txt) VALUES (1, 'row 1 old text')" ) ) # step 0.1 - create Dataframe to UPSERT df = pd.Dataframe( [(2, "new row 2 text"), (1, "row 1 new text")], columns=["id", "txt"] ) # step 1 - upload Dataframe to temporary table df.to_sql("#temp_table", conn, index=False, if_exists="replace") # step 2 - merge temp_table into main_table conn.execute( sa.text(""" UPDATE main SET main.txt = temp.txt FROM main_table main INNER JOIN #temp_table temp ON main.id = temp.id """ ) ) conn.execute( sa.text(""" INSERT INTO main_table (id, txt) SELECt id, txt FROM #temp_table WHERe id NOT IN (SELECt id FROM main_table) """ ) ) # step 3 - confirm results result = conn.execute(sa.text("SELECt * FROM main_table ORDER BY id")).fetchall() print(result) # [(1, 'row 1 new text'), (2, 'new row 2 text')]


