【问题标题】:Python return error when trying to send a MySQL query that contains MySQL variables尝试发送包含 MySQL 变量的 MySQL 查询时 Python 返回错误
【发布时间】:2020-02-06 16:20:31
【问题描述】:

我正在尝试通过使用 Python 发送 MySQL 查询来从 MySQL 数据库中检索数据。

当我在 MySQL 工作台中发送 MySQL 查询时,它运行得非常好。

当我使用 Python(在 Jupyter Notebook 中)尝试相同的操作时,它会返回错误。

Python 代码:

import pymysql
import pandas as pd

def run_mysql(SQLQ):
    conn = pymysql.connect(host='IP address', user='username', passwd='password', db='database name')
    df = pd.read_sql(SQLQ, conn)
    conn.close()
    return df

mysql_query = '''set @Yesterday = curdate() -1 ;
                SELECT * FROM mt4_daily
                where date(time) = date(@Yesterday)
                '''
df = run_mysql(mysql_query)
display(df)

错误:

DatabaseError: Execution failed on sql 'set @Yesterday = curdate() -1 ;
                SELECT * FROM mt4_daily
                where date(time) = date(@Yesterday)
                ': (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'SELECT * FROM mt4_daily\n                where date(time) = date(@Yesterday)' at line 2")

如果我删除 MySQL Query 中的变量,它运行良好:

import pymysql
import pandas as pd

def run_mysql(SQLQ):
    conn = pymysql.connect(host='IP address', user='username', passwd='password', db='database name')
    df = pd.read_sql(SQLQ, conn)
    conn.close()
    return df

mysqlquery = '''SELECT * FROM mt4_daily
                where date(time) = date(curdate() -1)
                '''
df = run_mysql(mysqlquery)
display(df)

我做错了什么?


最终解决方案:

感谢Prashant Sharma 的解决方案。

我对其进行了一些调整,使其返回一个 pandas 数据帧,并允许在 Select 查询之前传递一个变量列表。

代码如下:

import pymysql
import pandas as pd

def run_mysql(SQLQ,MySQL_Variable_List=''):
    try:
        conn = pymysql.connect(host='Server IP', user='UserName', passwd='Password', db='Database name')
        cursor = conn.cursor()
        for i in MySQL_Variable_List:
            cursor.execute(i)
        df = pd.read_sql(SQLQ, conn)
    except Exception as e:
        print(str(e))
    finally:
        cursor.close()
        conn.close()
        return df

MySQL_Variable_List = ["set @Yesterday = curdate() -1 ;"]
SQLQ = "SELECT * FROM mt4_daily where date(time) = date(@Yesterday) limit 10"
df1 = run_mysql(MySQL_Variable_List,SQLQ)

display(df1)

【问题讨论】:

  • 查询字符串中有一个换行符\n。尝试使用原始字符串文字 (r'''<query>''')
  • 试过了。没用。同样的错误。

标签: python mysql sql python-3.x


【解决方案1】:

下面的代码完成了这项工作,已经测试过了。如果出现问题,您可能需要纠正一些缩进问题。

import pymysql
def run_mysql(query1, query2):
    try:
      conn = pymysql.connect(host='localhost', user='root', passwd='', db='data_new_es')
      cursor = conn.cursor()
      cursor.execute(query1)
      cursor.execute(query2)
      row = cursor.fetchone()
      print(row)
 except Exception as e:
     print(str(e))
 finally:
     cursor.close()
     conn.close()

mysqlquery1 = "set @Yesterday = curdate() -1 ;"
mysqlquery2 = "select * from abcde where date(accrual_date) = 
date(@Yesterday)"
df1 = run_mysql(mysqlquery1,mysqlquery2)

【讨论】:

  • 像魅力一样工作!
【解决方案2】:

尝试将它们作为两个单独的查询运行。

mysql_query = '''set @Yesterday = curdate() -1 ;'''
df = run_mysql(mysql_query)
mysql_query = '''SELECT * FROM mt4_daily
                where date(time) = date(@Yesterday)
                '''
df = run_mysql(mysql_query)

【讨论】:

  • 这不起作用并且不会起作用,因为您向服务器发送明显不同的查询。服务器无法知道@Yesterday 连接在两者之间。感谢您尝试提供帮助!
【解决方案3】:

我想是因为有两个语句,而这个函数只允许同时读取和执行一个。根据pandas read_sql documentetation 可以使用read_sql "params" 关键字参数来解决这个问题,并将@Yesterday 的值计算移到python 端:

import pymysql
import pandas as pd

from datetime import datetime, timedelta

def run_mysql(SQLQ, params):
    conn = pymysql.connect(host='IP address', user='username', passwd='password', db='database name')
    df = pd.read_sql(SQLQ, conn, params=params)
    conn.close()
    return df

mysqlquery = '''SELECT * FROM mt4_daily
                where date(time) = date(%(yesterday)s)
             '''
yesterday = datetime.date(datetime.now())- timedelta(days=1)
params = {'yesterday': yesterday}
df = run_mysql(mysqlquery, params)
display(df)

我无法执行代码,但想法是这样的。

【讨论】:

  • 是的,计算日期可以移到 Python 端,它肯定会解决这个特殊问题。但是,我正在尝试学习如何从 Python 发送 MySQL 变量,而您的解决方案避免了它。不过感谢您的意见!
猜你喜欢
  • 2015-10-24
  • 1970-01-01
  • 2012-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-26
  • 2013-11-07
  • 2016-12-16
相关资源
最近更新 更多