通过 PyMySQL 执行时,在 MySQL 终端中运行的查询失败
A query that works in MySQL terminal fails when executed via PyMySQL
我在下面提供了三个示例 SQL 查询。这些中的每一个都工作正常,在 MySQL [db] >
环境中直接从终端执行时返回预期的 table 输出。
这些查询彼此保存在名为 queries.py
的 python 文档中。当通过 pymysql
传递给数据库时,后两个查询工作正常,但第一个 returns 是一个空数组。
我查看了 , this post, and this post,其中 none 似乎正在解决这个问题。
这是我在 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
的样子。这些查询中的每一个 returns 在 MySQL 中执行时都期望输出,但是第一个 VETTED
、returns 通过 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`;"""
我想你需要 四个 个反斜杠在 Python 字符串文字中来表示 两个 个反斜杠字符 [=52] =], 表示一个反斜杠字符。
MySQL 在字符串文字中需要 两个 个反斜杠来表示一个反斜杠字符。您的 SQL 文本在 MySQL 中有效,因为字符串文字包含 两个 反斜杠字符。
但是在 Python 代码中,发送到 MySQL 的 SQL 语句仅包含 单个 反斜杠字符。
那是因为 Python 也需要 两个 字符串文字中的反斜杠来表示反斜杠字符,就像 MySQL 一样。
所以,在 Python...
"""CRM\Bundle"""
^^
表示只包含一个个反斜杠字符的字符串:'CRM\Bundle'
获取包含两个个反斜杠字符的字符串:'CRM\Bundle'
您需要在 Python 文字中使用 四个 反斜杠,如下所示:
"""CRM\\Bundle"""
^^^^
我在下面提供了三个示例 SQL 查询。这些中的每一个都工作正常,在 MySQL [db] >
环境中直接从终端执行时返回预期的 table 输出。
这些查询彼此保存在名为 queries.py
的 python 文档中。当通过 pymysql
传递给数据库时,后两个查询工作正常,但第一个 returns 是一个空数组。
我查看了
这是我在 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
的样子。这些查询中的每一个 returns 在 MySQL 中执行时都期望输出,但是第一个 VETTED
、returns 通过 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`;"""
我想你需要 四个 个反斜杠在 Python 字符串文字中来表示 两个 个反斜杠字符 [=52] =], 表示一个反斜杠字符。
MySQL 在字符串文字中需要 两个 个反斜杠来表示一个反斜杠字符。您的 SQL 文本在 MySQL 中有效,因为字符串文字包含 两个 反斜杠字符。
但是在 Python 代码中,发送到 MySQL 的 SQL 语句仅包含 单个 反斜杠字符。
那是因为 Python 也需要 两个 字符串文字中的反斜杠来表示反斜杠字符,就像 MySQL 一样。
所以,在 Python...
"""CRM\Bundle"""
^^
表示只包含一个个反斜杠字符的字符串:'CRM\Bundle'
获取包含两个个反斜杠字符的字符串:'CRM\Bundle'
您需要在 Python 文字中使用 四个 反斜杠,如下所示:
"""CRM\\Bundle"""
^^^^