Reputation: 567
This has been a bit frustrating today. I'm sure its something simple that I'm overlooking. See code below (simplified for example sake):
def dbUpsert(sqlQuery, sqlValues):
# Connect to the database
connection = pymysql.connect(host='localhost',
user='db_user',
password='###',
db='garden',
charset='utf8mb4',
cursorclass=pymysql.cursors.DictCursor)
try:
with connection.cursor() as cursor:
# Create a new record
cursor.execute(sqlQuery, sqlValues)
# Commit the changes
connection.commit()
finally:
connection.close()
sqlValues = real_plants, datetime.datetime.today().strftime('%Y-%m-%d'), 10
print (sqlValues)
##### Output: ('roses', '2020-02-19', 10)
sqlQuery = """
INSERT INTO summ_plants_day
(
real_plants, d_date, acc_plants
)
VALUES (%s, %s, %s)
ON DUPLICATE KEY UPDATE
real_plants = %s,
d_date = %s,
acc_plants = %s
"""
dbUpsert(sqlQuery, sqlValues)
In my database, I have 4 columns. One is an auto-increment primary key, real_plants
and d_date
together form an index, and acc_plants
is the value I want to update / insert.
If an entry for roses
exists in table summ_plants_day
for the d_date
I want to UPDATE
, otherwise I want to INSERT
.
Here is the error:
Traceback (most recent call last):
in dbUpsert
cursor.execute(sqlQuery, sqlValues)
in execute
query = self.mogrify(query, args)
in mogrify
query = query % self._escape_args(args, conn)
TypeError: not enough arguments for format string
Also, I used %s
based on W3Schools examples. I saw conflicting information online while Googling my issue, is this proper/modern format to protect against SQL injection?
Upvotes: 3
Views: 579
Reputation: 222482
I would suggest using the VALUES()
syntax in the ON DUPLICATE KEY UPDATE
clause. This avoids the need to pass the same variable twice, so it should work just fine with your existing code:
INSERT INTO summ_plants_day (real_plants, d_date, acc_plants)
VALUES (%s, %s, %s)
ON DUPLICATE KEY UPDATE
real_plants = VALUES(real_plants),
d_date = VALUES(d_date),
acc_plants = VALUES(acc_plants)
Upvotes: 6