Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带变量的MySql read_sql python查询@_Python_Mysql_Pandas_Variables - Fatal编程技术网

带变量的MySql read_sql python查询@

带变量的MySql read_sql python查询@,python,mysql,pandas,variables,Python,Mysql,Pandas,Variables,我知道Python中的查询可以使用执行查询中的?或%s进行参数化 但是,我有一些长查询,它将使用在查询开始时定义的常量变量 Set @my_const = 'xyz'; select @my_const; -- Query that use @my_const 40 times select ... coalesce(field1, @my_const), case(.. then @my_const)... 我希望对来自Mysql的查询进行尽可能少的修改。因此,与其将查询修改为 pd.rea

我知道Python中的查询可以使用执行查询中的
%s
进行参数化

但是,我有一些长查询,它将使用在查询开始时定义的常量变量

Set @my_const = 'xyz';
select @my_const;
-- Query that use @my_const 40 times
select ... coalesce(field1, @my_const), case(.. then @my_const)...
我希望对来自Mysql的查询进行尽可能少的修改。因此,与其将查询修改为

pd.read_sql(select ... coalesce(field1, %s), case(.. then %s)... , [my_const, my_const, my_const, ..]
,我可以沿着初始查询的行写一些东西。但是,在尝试以下操作时,我得到一个
TypeError:“NoneType”对象不可编辑

query_str = "Set @null_val = \'\'; "\
    " select @null_val"
erpur_df = pd.read_sql(query_str, con = db)
知道如何使用Mysql查询中定义的原始变量吗?

原因

query_str = "Set @null_val = \'\'; "\
    " select @null_val"
erpur_df = pd.read_sql(query_str, con = db)
抛出该异常是因为您所做的只是将null_值设置为“”,然后选择该
'
-您希望它给您带来什么EDIT
read\u sql
似乎一次只执行一个查询,当第一个查询不返回任何行时,会导致该异常。 如果您将它们分成两个调用来读取sql,那么它实际上会在第二个调用中返回
@null value
的值。由于这种行为,
read\u sql
显然不是一种很好的方法。我强烈建议您使用下面我的建议之一

为什么要在SQL中使用“@”设置变量

您可以尝试使用字符串格式的
.format
样式

像这样:

query_str = "select ... coalesce(field1, {c}), case(.. then {c})...".format(c=my_const)
pd.read_sql(query_str)
请记住,如果您这样做,并且您的
my_const
是用户输入,那么您需要手动清理它以防止SQL注入

另一种可能性是使用如下参数:

query_str = "select ... coalesce(field1, %(my_const)s, case(.. then %(my_const)s)..."
pd.read_sql(query_str, params={'my_const': const_value})
但是,这取决于您使用的数据库驱动程序

从:

检查数据库驱动程序文档,了解这五种语法中的哪一种 支持PEP 249的paramstyle中描述的样式。为了 psycopg2,使用%(名称)s,因此使用参数={'name':'value'}


谢谢你的回复。您可以尝试将@null_val设置为其他字符串,同样的错误也会发生。我只是举了个例子。其次,如前所述,我希望查询字符串尽可能少修改,因为查询相当长;python版本上的modif越多,每次原始查询更改并将其粘贴到python时,我必须执行的modif就越多。您的解决方案似乎属于使用%s的类别。最后,您能详细说明一下“清理参数”吗?如果您能解释一下为什么不想更改查询,这会有所帮助?在python中使用参数化只需要进行一个查询,而且您需要字符串格式的查询才能与
read\u sql
一起使用。至于清理参数,如果一个参数是由外部用户提供的,那么该用户可以提供一些SQL,在没有清理的情况下,可以执行诸如“DROP TABLE”之类的查询。我建议你用谷歌搜索一下“SQL注入”,以便更好地了解风险。为了简单起见,也为了让维护它的人远离复杂性。我不会一直支持它。当一个人在Mysql中修改查询并进行测试以获得他想要的内容时,他可以将粘贴复制到python中,而无需向全世界发出“哦,你修改了什么?下面是在python中需要执行的步骤:1/复制粘贴。2/@null_值替换为{s}3/计算{s}的数量,然后创建一个大小相同的元组,等等。我知道SQL注入。我只是想知道“消毒参数”是什么意思请看我上面的编辑。滥用read_-sql来做一些它不打算做的事情并不是为了简单。使用上述两种方法,您都不需要长度相同的元组。“您的长查询”。格式(c=value)清晰、简单,可与read_sql配合使用。至于从MySQL复制,{c}的@my_const很容易找到/替换。三重引号(使用“或”)是Python中用于多行字符串的一种特殊情况。在这种情况下使用“”或just基本相同。如果要在字符串中转义引号,请对整个字符串使用相反的引号样式(即在单引号内使用双引号,反之亦然)或者必须使用\来转义。