如何在Python中的SQL语句中使用变量?

时间:2009-05-23 20:20:34

标签: python sql

好的,所以我不具备Python方面的经验。

我有以下Python代码:

cursor.execute("INSERT INTO table VALUES var1, var2, var3,")

其中var1是一个整数,var2& var3是字符串。

如何在没有python的情况下编写变量名,包括它们作为查询文本的一部分?

6 个答案:

答案 0 :(得分:77)

cursor.execute("INSERT INTO table VALUES (%s, %s, %s)", (var1, var2, var3))

请注意,参数将作为元组传递。

数据库API可以正确转义和引用变量。注意不要使用字符串格式化运算符(%),因为

  1. 它不会进行任何转义或引用。
  2. 很容易受到不受控制的字符串格式攻击,例如SQL injection

答案 1 :(得分:56)

允许Python DB-API的不同实现使用不同的占位符,因此您需要找出您正在使用的占位符 - 它可能是(例如使用MySQLdb):

cursor.execute("INSERT INTO table VALUES (%s, %s, %s)", (var1, var2, var3))

或(例如,使用Python标准库中的sqlite3):

cursor.execute("INSERT INTO table VALUES (?, ?, ?)", (var1, var2, var3))

或其他人(在VALUES之后你可以拥有(:1, :2, :3),或“命名样式”(:fee, :fie, :fo)(%(fee)s, %(fie)s, %(fo)s)你传递的是dict而不是地图作为第二个对execute)的论证。检查您正在使用的DB API模块中的paramstyle字符串常量,并在http://www.python.org/dev/peps/pep-0249/查找paramstyle以查看所有参数传递样式!

答案 2 :(得分:32)

很多方面。 不要在实际代码中使用最明显的一个(%s%),它对attacks开放。

此处复制粘贴 from pydoc of sqlite3

# Never do this -- insecure!
symbol = 'RHAT'
c.execute("SELECT * FROM stocks WHERE symbol = '%s'" % symbol)

# Do this instead
t = ('RHAT',)
c.execute('SELECT * FROM stocks WHERE symbol=?', t)
print c.fetchone()

# Larger example that inserts many records at a time
purchases = [('2006-03-28', 'BUY', 'IBM', 1000, 45.00),
             ('2006-04-05', 'BUY', 'MSFT', 1000, 72.00),
             ('2006-04-06', 'SELL', 'IBM', 500, 53.00),
            ]
c.executemany('INSERT INTO stocks VALUES (?,?,?,?,?)', purchases)

如果您需要更多示例:

# Multiple values single statement/execution
c.execute('SELECT * FROM stocks WHERE symbol=? OR symbol=?', ('RHAT', 'MSO'))
print c.fetchall()
c.execute('SELECT * FROM stocks WHERE symbol IN (?, ?)', ('RHAT', 'MSO'))
print c.fetchall()
# This also works, though ones above are better as a habit as it's inline with syntax of executemany().. but your choice.
c.execute('SELECT * FROM stocks WHERE symbol=? OR symbol=?', 'RHAT', 'MSO')
print c.fetchall()
# Insert a single item
c.execute('INSERT INTO stocks VALUES (?,?,?,?,?)', ('2006-03-28', 'BUY', 'IBM', 1000, 45.00))

答案 3 :(得分:18)

http://www.amk.ca/python/writing/DB-API.html

当您只是将变量值附加到语句时要小心: 想象一下用户自称';DROP TABLE Users;' - 这就是为什么你需要使用sql escaping,当你以一种体面的方式使用cursor.execute时,Python会为你提供。网址中的示例是:

cursor.execute("insert into Attendees values (?, ?, ?)", (name,
seminar, paid) )

答案 4 :(得分:0)

与此同时,还有一种使用f-strings的方法:

cursor.execute(f"INSERT INTO table VALUES {var1}, {var2}, {var3},")

答案 5 :(得分:0)

对于没有经验的Python用户,提供单个值的语法可能会造成混淆。

给出查询

INSERT INTO mytable (fruit) VALUES (%s)

传递给cursor.execute的值即使是单例也必须仍然是tuple,因此我们必须提供单个元素元组,例如:(value,)

cursor.execute("""INSERT INTO mytable (fruit) VALUES (%s)""", ('apple',))