我正在开发python应用程序,它应该与数据库一起工作。我遇到了一个问题。在PHP中,我可以直接通过$符号对变量进行查询,但在python中,我正在编写以下代码:
query = "INSERT INTO shops (id, shop_id, shop_url, shop_name, shop_cat, datas)" + "VALUES("+count+", "+str(shop_id)+", "+shop_url+", "+shop_name+", "+shop_cat+", "+pdfs+datas+");"
有没有像PHP中那样的方法,我的意思是在一个字符串中进行?
您应该永远不要像那样连接SQL字符串。您正在请求SQL注入。
在DB API中使用内置转义:
cursor.execute("INSERT INTO shops (id, shop_id, shop_url, shop_name, shop_cat, datas) VALUES (%d, %s, %s, %s, %s, %s)", (count, show_id, shop_url, shop_name, shop_cat, pdfs + datas))
并且您的查询将被正确地转义。
通常,在Python中,可以使用"+"来连接字符串。您还可以使用类似printf的语法"Hello%s!"%"World"和较新的格式化语法"Hello{0}".format('World!')
不能直接使用,但可以使用字符串格式化操作:
query = "...VALUES(%d, %d, %s, %s)" % (some_int, some_other_int, some_string, some_other_string)
然而,在您的情况下,这是一个坏主意。对于SQL查询中的这类事情,您应该这样做:
query = "INSERT INTO ... VALUES(?, ?, ?, ?)"
cursor.execute(query, some_int, some_other_int, some_string, some_other_string)
这是防止SQL注入的最简单、最有效的方法。所有主要的SQLPython模块(至少MySQL、SQLite、PostgreSQL)都支持这种语法。
有关这方面的更多详细信息,请参阅sqlite3模块文档。
如何使用格式化:
query = (
"INSERT INTO shops (id, shop_id, shop_url, shop_name, shop_cat, datas)"
"VALUES(%d, %s, %s, %s, %s, %s%s);" %
(count, show_id, shop_url, shop_name, shop_cat, pdfs, datas))
或者像这样:
query = (
"INSERT INTO shops (id, shop_id, shop_url, shop_name, shop_cat, datas)"
"VALUES(%(count)d, %(show_id)s, %(shop_url)s, %(shop_name)s,"
" %(shop_cat)s, %(pdfs)s%(datas)s);" % vars())
不要像那样通过连接字符串来创建查询,使用像这样的参数化查询
cursor.execute(""INSERT INTO shops (id, shop_id, shop_url, shop_name, shop_cat, datas) VALUES(?,?,?,?,?,?)", (count, shop_id, shop_url, shop_name, shop_cat, datas))
从长远来看,这将为您省去很多麻烦,而且运行速度更快。VALUES
之后的符号?
可以在不同的API 之间变化
首先,以这种方式构造SQL查询是一种糟糕的做法。您应该使用参数化查询。现在,Python的DB-API2.0(PEP-249)定义了几个参数样式:
paramstyle
String constant stating the type of parameter marker formatting expected by the interface. Possible values are [2]: 'qmark' Question mark style, e.g. '...WHERE name=?' 'numeric' Numeric, positional style, e.g. '...WHERE name=:1' 'named' Named style, e.g. '...WHERE name=:name' 'format' ANSI C printf format codes, e.g. '...WHERE name=%s' 'pyformat' Python extended format codes, e.g. '...WHERE name=%(name)s'
例如,对于MySQL,默认的参数样式是"format"(即C样式),因此您可以执行
cursor.execute("INSERT INTO shops (id, shop_id, shop_url, shop_name, shop_cat, datas) VALUES (%s, %s, %s, %s, %s, %s)" , (count, shop_id, shop_url, shop_name, shop_cat, pdfs+datas)
首先,不要创建这样的SQL查询。也就是说,这就是如何在Python中获得命名(PHP风格)变量插值
使用字符串模板。这里有一个例子:
from string import Template
foo = Template('All that $does is $metal.')
bar = foo.substitute(does='glitters', metal='gold')
print(bar) // All that glitters is gold.