sqlalchemy 双引号列表项

sqlalchemy double quoting list items

我在使用 "WHERE IN" 语句时遇到原始查询的引用问题。 SQLAlchemy 正在列表中的单引号周围添加双引号...

我正在尝试执行的查询

sql_query = "SELECT col1, col2, col3 FROM preferences WHERE recipient IN :recipients"
preferences = sqlsession.execute(sql_query,dict(recipient=tuple(message.recipients))

message.recipients 是一个像这样的列表: ["recipient1","recipient2","recipient3"]

SQLAlchemy 调试日志

INFO:sqlalchemy.engine.base.Engine:SELECT col1, col2, col2 FROM preferences WHERE recipient IN %s
INFO:sqlalchemy.engine.base.Engine:(('recipient1', 'recipient2', 'recipient3'),)

Mariadb 日志

9 Query     SELECT col1, col2, col3 FROM preferences WHERE recipient IN ("'recipient1'", "'recipient1'", "'recipient1'") <-- double quotes around single quotes

我有 运行 strace 来查看这些引号的添加位置,这是 sqlalchemy 的错误。

Table 架构:

CREATE TABLE `preferences` (
  `recipient` varchar(255) COLLATE latin1_general_ci NOT NULL,
  `col1` tinyint(1) NOT NULL DEFAULT '1',
  `col2` tinyint(1) NOT NULL DEFAULT '1',
  `col3` tinyint(1) NOT NULL DEFAULT '1',
  PRIMARY KEY (`recipient`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci

环境

CentOS 7
python-sqlalchemy.x86_64 0.9.7-3.el7 epel

你好。

根据 gmane.comp.python.sqlalchemy.user 的建议,您可以使用 autoload 功能。

总结Michael Bayer答案:

t = sqlalchemy.Table(
  'preferences',             # your table name
  sqlalchemy.MetaData(),
  autoload=True,
  autoload_with=sqlsession,
)

query = sqlalchemy.select([t.c.col1, t.c.col2, t.c.col3]) \
  .where(t.c.recipient.in_(message.recipients))

preferences = query.fetchall()

在我的情况下,我将不得不 "autoload" 一堆表,这并不是很方便,因为它们有复杂的连接。

我结束了使用以下行中的内容:

query = "SELECT col1, col2, col3 FROM preferences\nWHERE recipient IN (%s);" % (
  ', '.join(['%s'] * len(message.recipients)
)
result = sqlsession.execute(query, (message.recipients,)) # notice the ","

我们的想法是使用将提供给 IN 表达式的项目数来构建查询;通过这样做,您将获得自动转义功能的好处,并与所有数据库后端兼容(据我所知)。

您可以通过以下方式查看生成的查询:

>>> print result._saved_cursor._last_executed
SELECT col1, col2, col3 FROM preferences
WHERE recipient IN ('recipient1', 'recipient2', ...);