【问题标题】:A query that works in MySQL terminal fails when executed via PyMySQL通过 PyMySQL 执行时,在 MySQL 终端中工作的查询失败
【发布时间】:2016-10-06 21:33:24
【问题描述】:

我在下面提供了三个示例 SQL 查询。这些中的每一个都可以正常工作,在MySQL [db] > 环境中直接从终端执行时返回预期的表输出。

这些查询彼此都保存在名为queries.py 的python 文档中。当通过pymysql 传递到数据库时,后两个查询工作正常,但第一个查询返回一个空数组。

我查看了this postthis postthis post,但似乎都没有解决这个问题。

这是我用来在 Python 中测试的示例代码(版本 3.5):

import pymysql
import params 
import queries 

conn = pymysql.connect(
  host = params.HOST,
  user = params.USER,
  password = params.PWD,
  db = 'db',
  charset='utf8',
  cursorclass=pymysql.cursors.DictCursor,
  autocommit = True)

test_queries = [queries.VETTED, queries.CREATED, queries.CLOSED_OPPS]
with conn.cursor() as cursor:
    for query in test_queries: 
        cursor.execute(query)
        print(cursor.fetchall())

() #..blank output -- doesn't make sense because corresponding query works in MySQL env
[...] #..expected output from query 2
[...] #..expected output from query 3

这是queries.py 的样子。这些查询中的每一个在 MySQL 中执行时都会返回预期的输出,但第一个查询 VETTED 在通过 pymysql 传递到数据库时返回一个空白数组:

VETTED = """
SELECT
  date_format(oa.logged_at, '%Y-%m-%d')  as `action_date`,
  count(1) `count`
FROM
  crm_audit_field oaf,
  crm_audit oa,
  crm_sales_lead lead
WHERE
  oa.id = oaf.audit_id AND
  oaf.field = 'status' AND
  (
    oaf.new_text = 'Qualified' OR
    oaf.new_text = 'Disqualified' OR
    oaf.new_text = 'Canceled'
  ) AND
  oa.object_class = 'CRM\\Bundle\\SalesBundle\\Entity\\Lead' AND
  lead.id = oa.object_id AND
  (lead.status_id = 'qualified' OR lead.status_id = 'canceled')
GROUP BY
  `action_date`;"""

CREATED = """
SELECT
  DATE_FORMAT(lead.createdat, '%Y-%m-%d') as `creation_date`,
  count(1)
FROM
  crm_sales_lead `lead`
GROUP BY
  creation_date;"""

CLOSED_OPPS = """
SELECT
  date_format(closed_at, '%Y-%m-%d') `close_date`,
  count(1) `count`
FROM
  crm_sales_opportunity
WHERE
  status_id = 'won'
GROUP BY
  `close_date`;"""

【问题讨论】:

  • 有趣...看来您正确使用了引号,我的谦虚建议是简化您的 where 子句并逐渐添加条件。
  • Python 正在处理字符串文字中的一些反斜杠字符。您需要在 Python 中将字符串文字中的反斜杠加倍。一共四个反斜杠,获取SQL文本中的两个反斜杠传递给MySQL,让MySQL将其视为一个反斜杠字符。

标签: python mysql python-3.x pymysql


【解决方案1】:

我认为您需要在 Python 字符串文字中使用 四个 个反斜杠来表示 MySQL 所需的 两个 反斜杠字符,以表示一个反斜杠字符。

MySQL 在字符串文字中需要 两个 反斜杠来表示反斜杠字符。您拥有的 SQL 文本在 MySQL 中有效,因为字符串文字包含 两个 反斜杠字符。

但在 Python 代码中,发送到 MySQL 的 SQL 语句只包含单个反斜杠字符。

这是因为 Python 在字符串文字中也需要 两个 反斜杠来表示反斜杠字符,就像 MySQL 一样。

所以,在 Python 中...

  """CRM\\Bundle"""
        ^^

表示只包含一个反斜杠字符的字符串:'CRM\Bundle'

获取包含两个反斜杠字符的字符串:'CRM\\Bundle'

您需要在 Python 文字中使用 四个 反斜杠,如下所示:

  """CRM\\\\Bundle"""
        ^^^^

【讨论】:

  • 搞定了,这正是问题所在。我以前用其他应用程序看到过这个——这次也应该抓住它。谢谢!
猜你喜欢
  • 1970-01-01
  • 2012-10-21
  • 2012-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-06
  • 2016-03-12
  • 1970-01-01
相关资源
最近更新 更多