如果数据存在,则更新行



我有以下SQL,旨在在DB中创建新记录或更新现有记录。

sql = """INSERT INTO table (v1, v2, v3, v4, v5, v6)
VALUES (?, ?, ?, ?, ?, ?)
ON CONFLICT(v5) DO UPDATE
SET v1 = ?, v3 = ?, v6 = ?
"""
self.curr.execute(sql,(
v1, v2, v3, v4, v5, v6,
# below are the values for eventual update 
v1, v3, v6)
)

这工作得很好,但是,我试图实现executemany()的批处理创建行,并保持ON CONFLICT逻辑。

我知道它看起来像这样:

data = [
('Jane', date(2005, 2, 12)),
('Joe', date(2006, 5, 23)),
('John', date(2010, 10, 3)),
]
sql = """
INSERT INTO employees (first_name, hire_date) 
VALUES (%s, %s)
ON CONFLICT(first_name) DO UPDATE
SET date = %S
"""
cursor.executemany(sql, data)

但我不太确定如何传递用于更新的列值(hire_date),如果一行first_name已经存在

我是否在数据数组中传递另外3个元组,其值用于最终更新?

我在网上找不到我需要的任何具体资源,所以任何帮助都会很感激。

您可以将EXCLUDED表限定符添加到列名中:

data = [
('Jane', date(2005, 2, 12)),
('Joe', date(2006, 5, 23)),
('John', date(2010, 10, 3)),
]
sql = """
INSERT INTO employees (first_name, hire_date) 
VALUES (?, ?)
ON CONFLICT(first_name) DO UPDATE
SET hire_date = EXCLUDED.hire_date
"""
cursor.executemany(sql, data)

因为SQL中有三个占位符,所以需要绑定三个参数。因此,请重复日期值。顺便说一下,sqlite3使用qmark,?,作为占位符,在您的第一个示例中使用,并确保commit

data = [
('Jane', date(2005, 2, 12), date(2005, 2, 12)), 
('Joe', date(2006, 5, 23), date(2006, 5, 23)), 
('John', date(2010, 10, 3), date(2010, 10, 3)), 
] 
sql = """INSERT INTO employees (first_name, hire_date) 
VALUES (?, ?) 
ON CONFLICT(first_name) DO 
UPDATE SET hire_date = ? 
"""
cursor.executemany(sql, data)
conn.commit()