【问题标题】:Executing query through pymysql not returning the same results as running in MySQL通过 pymysql 执行查询不会返回与在 MySQL 中运行相同的结果
【发布时间】:2018-07-06 09:38:30
【问题描述】:

我是 Python 和 PyMySQL 的新手,所以我可能有一些配置错误。

我正在毫无问题地连接到 MySQL。我在一张桌子上进行了 SELECTDESC 测试,并且能够查看结果。

我现在有一个查询,我将日期参数替换为并希望返回列的计数(客户)和客户总数乘以一个值。

客户数量返回正确,但产品计算返回。在执行查询之前,我将其打印到控制台并复制到 MySQLWorkbench 以运行,并返回正确的值。

在我的 main 模块中,我连接到数据库并获得一个游标。然后我获取要在查询中使用的日期值并调用执行查询的函数。

connection = dbConnection()
cursor = connection.cursor()
startDate = input("enter start date (yyyy-mm-dd): ").strip()
endDate = input("enter end date (yyyy-mm-dd): ").strip()
my_queries.queryTotals(cursor, startDate, endDate)
connection.close()

在我的 my_queries 模块中,我有查询并将输入的日期替换为查询字符串,然后执行查询并获取结果:

totalsSQL = '''select
@total:=count(cus.customer_id) as customers, format(@total * 1.99, 2) as total
from customer cus
join membership mem on mem.membership_id=cus.current_membership_id
where mem.request='START'
and (mem.purchase_date > (unix_timestamp(date('{}'))*1000)  and mem.purchase_date < unix_timestamp(date('{}'))*1000);'''

formattedSQL = totalsSQL.format(startDate, endDate)

cursor.execute(formattedSQL)
result = cursor.fetchone()

我得到 (32, None) 的结果,而不是获取第二列值的数值。

我在这里错过了什么?

谢谢。

【问题讨论】:

    标签: mysql python-3.x pymysql


    【解决方案1】:

    您不能将变量用于聚合函数,稍后在同一个SELECT 列表中引用它。在选择所有行之前,聚合不会获得它们的值,但是在选择行时会计算其他列。

    只需在两个地方都使用COUNT(*)

    SELECT COUNT(*) AS customers, FORMAT(COUNT(*) * 1.99, 2) AS total
    join membership mem on mem.membership_id=cus.current_membership_id
    where mem.request='START'
    and (mem.purchase_date > (unix_timestamp(date('{}'))*1000) 
    and mem.purchase_date < unix_timestamp(date('{}'))*1000)
    

    另外,为了防止 SQL 注入,您应该使用参数化查询,而不是用 format() 替换变量。

    totalsSQL = '''
        SELECT COUNT(*) AS customers, FORMAT(COUNT(*) * 1.99, 2) AS total
        join membership mem on mem.membership_id=cus.current_membership_id
        where mem.request='START'
        and (mem.purchase_date > (unix_timestamp(date(%s))*1000) 
        and mem.purchase_date < unix_timestamp(date(%s))*1000)
    '''
    cursor.execute(totalsSQL, (startDate, endDate))
    

    【讨论】:

    • 做到了!我也会更改字符串替换。让我失望的是它确实适用于工作台。一定是时间上的侥幸。非常感谢。
    • 我不知道为什么它适用于工作台。我刚用 CLI 界面试了一下,还是不行。
    • 不要忘记变量在查询之间持续存在。因此,如果您尝试查询两次,第二次将使用第一次的计数。
    • 大概就是这样。每天学习新东西!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-08
    • 2020-09-27
    • 1970-01-01
    • 2016-09-29
    • 2015-02-09
    • 2013-10-05
    • 2020-05-15
    相关资源
    最近更新 更多