代码非常简单,我只是直接从控制台运行,同时,spider.table_名称='爬虫'
import MySQLdb
import scrapy
print (spider.table_name) # >> 'crawler'
db = MySQLdb.connect(........)
db.set_character_set('utf8')
mysql = db.cursor()
sql = "CREATE TABLE %s like r_template;"
mysql.execute(sql, (spider.table_name, ))
db.commit()
但我发现语法错误:
^{pr2}$看起来实际执行的sql语句是:
CREATE TABLE 'crawler' like r_template
单引号“”是如何生成的?如何防止它发生?
然后,我试着用更简单的方法:
mysql.execute(sql, ('crawler', ))
mysql.execute("CREATE TABLE %s like r_template", ('crawler', ))
错误仍然发生。
你不小心打开了通往神秘和冒险世界的大门。我的建议是:在看之前不要关上门。在
问题是,您试图在左侧传递占位符“”,但您与MySQL的接口只在“右侧”上工作。占位符用于值,而不是用于字段名或表。在
肤浅的解释
让我从另一个例子开始。在
合法的做法是:
如果变量是一个字符串,那么与pep249兼容的接口将正确地解释它:将其视为“在它周围加引号”(尽管它不是这样做的,否则它将为SQL注入打开大门;但这将说明这一点)。在
在等式的右边。在
但如果你写:
^{pr2}$如果值为“my_field”,则它将不起作用,因为它位于左侧。这不是接口的一部分。在
正如您所说,如果您应用相同的逻辑,它将“加引号”,因此您将得到:
这显然是没有道理的,因为你得到了你意想不到的报价(注意:再次说明,这不是发生的事情,但它说明了问题所在)。如果你还不明白你的逻辑。这是一个矛盾,显然出了问题。
但是等等!在
更深入的解释
理解pep249接口时,占位符的参数不会转换为字符串,然后放入字符串查询中,这一点很重要。它们被转换成它们的等价物(int等),并在较低的层次上进行处理(我想是在解析树或类似的结构中)。在
已指定将参数转换为值的机制。它不是为变量标识符而设计的,例如字段或表(这是一个更高级的用例)。在
说“标识符是一个变量”是一个非常先进的想法…我让您进入higher-order programming的奇妙世界。在
PEP249是否可以扩展到这一点?理论上是的,但这不是一个开放式的问题。在
解决方案
同时,您只剩下一个选项:在将字符串查询交给SQL引擎之前对其进行插值。在
我可以想象你周围的人恐惧的颤抖(别打开那扇门!)。但据我所知,如果你真的想要一个变量表名,那就是你必须要做的。在
这时,您可能想问自己为什么要使用变量表名?你这么做是为了别的事而懒散地解决问题吗?在这种情况下,我会回到惯常做法而忘记使表或字段变为变量。在
对于或两个数据库的情况,请参见使用数据库或的情况。在
如果是这样,只需小心使用字符串插值,以避免意外的SQL注入。您必须处理空白、特殊字符等不同的问题;一个好的做法是“引用”字段或表名,例如在标准MySQL中:
鉴于ANSI引用:
(如你所见,你并不遥远!)在
还要注意去掉可能会使解释器脱落的东西,比如分号。在
不管怎样,如果你想这样做,你需要在看不到海岸的地方,直接朝着日落的方向航行。你在吗h英雄向左侧的旅程。只要你接受没有救生员来救你,你就会享受这次冒险。在
使用.format而不是%s这将允许您在查询中避免使用单引号。 例如:
这应该行得通:)
相关问题 更多 >
编程相关推荐