为什么不能用pymysql中的格式函数替换占位符?

Why can't replace placeholder with format function in pymysql?

我如何创建 table mingyan.

CREATE TABLE `mingyan` (
  `tag` varchar(10) DEFAULT NULL,
  `cont` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

据说 {} 的字符串格式函数比占位符 %.
更像 pythonic 方式 在我的 scrapy 中将一些字段写入 table mingyan.

self.cursor.execute("insert into mingyan(tag, cont) values (%s, %s)",(item['tag'],item['cont']))

它在我的scrapy中工作正常,现在我用字符串格式函数替换占位符方式。

self.cursor.execute("insert into mingyan(tag, cont) values ({},{})".format(item['tag'],item['cont']))

scrapy 得到错误信息

pymysql.err.ProgrammingError: (1064, "You have an error in your SQL syntax; 

为什么不能用pymysql中的格式化函数替换占位符?

scrapy 文档中的项目。
item meaning in scrapy

简而言之:cursor.execute 中实现的参数替换与 Python 字符串格式不同,尽管使用了“%s”作为占位符;这就是为什么你会得到不同的结果。

数据库期望查询参数以特定方式被引用 - 被单引号或双引号甚至反引号包围。 Python 的 DBAPI standard 提供参数替换功能,以自动执行繁琐且容易出错的参数引用过程。

实现 DBAPI 标准的数据库驱动程序包自动将正确的引用规则应用于查询参数。因此,例如,给定此代码

cursor.execute("""INSERT INTO mytable (foo, bar) VALUES (%s, %s);""", ('bar', None))   

驱动程序将使用此 VALUES 子句生成 sql:

VALUES ('bar', NULL)

注意

  • "bar"在引号里
  • None 已转换为 NULL,未加引号

使用字符串格式化而不是 DBAPI 参数替换意味着您需要自己了解并应用这些规则,例如:

cursor.execute("""INSERT INTO mytable (foo) VALUES ('{}')""".format('bar'))

请注意格式占位符周围的引号。

MySQL 的引用规则在 question.

的答案中有详细讨论

我总是这样做

self.cursor.execute("insert into mingyan(tag, cont) values (%(tag)s, %(cont)s)", \
    {'tag': item['tag'], 'cont': item['cont']})