繁体   English   中英

字符串格式化sqlite3中的sql查询

[英]string formatting a sql query in sqlite3

我一直在玩 sqlite3,我得到了一个sqlite3.OperationalError: near "sweet": syntax error for this line of my code query_cursor.execute("INSERT INTO mcdonalds_menu VALUES(%d, %s, %f, %s, %d)" % (ids[num],names[num], price[num], descriptions[num], calories[num]))当我在 3 个单独的查询中输入值时,代码似乎有效,但我试图通过使用 for 循环使我的代码更加干燥。 到目前为止的代码:

import sqlite3

filename = sqlite3.connect("McDonalds_Menu.db")
query_cursor = filename.cursor()

def create_table():
    query_cursor.execute( "CREATE TABLE mcdonalds_menu (id INTEGER, name VARCHAR(20), price DECIMAL(3, 2), description TEXT, calories INTEGER)")

ids = range(1,4)
names = ["McFlurry", "Fillet-o-Fish", "McCafe"]
price = 1.50, 2.25, 0.99
descriptions = ["Delicious sweet icecream", "Best fish in the sea", "Freshly brewed Colombian coffee"]
calories = 220, 450, 75

def data_entry():
    for num in xrange(3):
        query_cursor.execute("INSERT INTO mcdonalds_menu VALUES(%d, %s, %f, %s, %d)" % (ids[num], names[num], price[num], descriptions[num], calories[num]))    
    filename.commit()

if __name__ == "__main__":
    create_table()
    data_entry()

是否可以使用循环对 sql 查询进行字符串格式化?

SQL 需要引用VALUES字符串。 整数和浮点数不需要被引用。

在下面的注释输出中,请注意 SQL VALUES包含“Fillet-o-Fish”和“Best fish in the sea”的未加引号的字符串:

sql = "INSERT INTO mcdonalds_menu VALUES(%d, %s, %f, %s, %d)".format(ids[num], names[num], price[num], descriptions[num], calories[num])
# INSERT INTO mcdonalds_menu VALUES(2, Fillet-o-Fish, 2.250000, Best fish in the sea, 450)

在字符串值周围添加一些转义引号会生成有效的 SQL:

sql = "INSERT INTO mcdonalds_menu VALUES(%d, \"%s\", %f, \"%s\", %d)" % (ids[num],names[num], price[num], descriptions[num], calories[num])
# INSERT INTO mcdonalds_menu VALUES(2, "Fillet-o-Fish", 2.250000, "Best fish in the sea", 450)

依赖 python 字符串操作的所有其他答案都是不安全的,可能无法正确转义字符串中的引号。

按照sqlite3 文档中的建议,最好的方法是使用 DB-API 的参数替换。 在您的示例中,它看起来像这样:

menu_items = [(1, 'McFlurry', 1.5, 'Delicious sweet icecream', 220),
              (2, 'Fillet-o-Fish', 2.25, 'Best fish in the sea', 450),
              (3, 'McCafe', 0.99, 'Freshly brewed Colombian coffee', 75)
              ]
c.executemany('INSERT INTO mcdonalds_menu VALUES (?,?,?,?,?)', menu_items)

使用 Python 3.6+,您可以使用 f 字符串简化这种引用混乱。 例如:

c.execute(f"select sql from sqlite_master where type='table' and name='{table_name}';")
for r in c.fetchall():
    print(r)

在这个片段中,需要注意的重要一点是 sql 字符串前面的f 这允许传入由大括号包围的变量,在我的示例中:'{table_name}'

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM