【问题标题】:(MySQLdb._exceptions.ProgrammingError) not enough arguments for format string(MySQLdb._exceptions.ProgrammingError) 格式字符串的参数不足
【发布时间】:2020-04-12 17:46:24
【问题描述】:

我正在使用以下查询从 mysql 数据库中读取数据:
设置:

conn = MySQLdb.connect(host='127.0.0.1', port=3306, user='**', passwd='**', db='***')
engine = create_engine('mysql+mysqldb://***')

sql = 'show tables like "{}"'.format('aTable_' + '%')

option-1:没关系

a1 = pd.read_sql_query(sql, conn)

option-2:这将引发错误:
ProgrammingError: (MySQLdb.exceptions.ProgrammingError) 格式字符串的参数不足 [SQL: 显示类似 "aTable%" 的表格] (此错误的背景:http://sqlalche.me/e/f405

a1 = pd.read_sql_query(sql, engine)

如果我想使用第二种样式(引擎作为参数)该怎么办?

【问题讨论】:

  • 您是否尝试过其他一些查询,一个简单的选择或一些琐碎的事情?
  • @luistm,对于简单的 sql 字符串,它适用于连接和引擎版本

标签: python pandas sqlalchemy mysql-python


【解决方案1】:

不要使用字符串格式将值传递给 SQL,而是使用占位符:

from sqlalchemy import text
engine = create_engine('mysql+mysqldb://***')
sql = text('SHOW TABLES LIKE :pattern')
a1 = pd.read_sql_query(sql, engine, params={'pattern': 'aTable_%'})

使用text() 允许您使用命名的paramstyle,而不管您使用的是什么DB-API 驱动程序。占位符可确保 or anyone else 不会意外地将意外 SQL 注入到查询中,例如将包含引号的字符串作为值传递。

在这种情况下,问题源于% 字符。如果不带参数调用 MySQLdb DB-API 驱动程序的 execute() 方法,它将不会尝试在查询中使用占位符。另一方面,SQLAlchemy 似乎正在传递 execute() 一个空的参数容器,这会触发尝试在查询字符串中使用占位符的代码路径,最终——转换参数之后到他们的 SQL 文字形式——是使用 %-formatting 完成的,所以错误“没有足够的参数用于格式字符串”:

In [4]: 'show tables like "aTable_%"' % ()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-4-4f31bc6a7bb6> in <module>()
----> 1 'show tables like "aTable_%"' % ()

TypeError: not enough arguments for format string

【讨论】:

  • 谢谢,将原始字符串包装成sqlalchemy.text()对象后,使用引擎版本可以,但是连接版本失败;为什么会有这种差异?我应该何时使用引擎以及何时使用连接?从 pandas.read_sql_query() 文档它接受引擎和连接。
  • text() 是一个 SQLAlchemy 构造,因此在使用 SQLAlchemy(引擎)时会用到它。它不适用于原始 DB-API 连接。尽管text() 转义%,即使您手动将值直接格式化为原始SQL 字符串,也不要这样做。使用占位符。
【解决方案2】:

我在 panda read_sql_query 上遇到了同样的问题并遇到以下错误:

ProgrammingError: (MySQLdb._exceptions.ProgrammingError) not enough arguments for format string[SQL: SELECT * FROM `alarms` 
                    WHERE 
                    (`Supplementary` NOT LIKE '%door%') 
                    AND 
                    ( `Supplementary` LIKE '%main%') 
                     )]

(此错误的背景:http://sqlalche.me/e/f405

它用 双 % 符号 解决了这个问题,如下所示:

(`Supplementary` NOT LIKE '%%door%%') AND ( `Supplementary` LIKE '%%main%%') 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-16
    • 2015-11-16
    • 2013-10-27
    • 1970-01-01
    • 2020-04-10
    • 2012-06-24
    • 2020-10-17
    相关资源
    最近更新 更多