mysql read\u sql python带变量查询@

5hcedyr0  于 2021-06-21  发布在  Mysql
关注(0)|答案(1)|浏览(315)

我知道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' object is not iterable ```
query_str = "Set @null_val = ''; "
" select @null_val"
erpur_df = pd.read_sql(query_str, con = db)

知道如何使用mysql查询中定义的原始变量吗?
hpxqektj

hpxqektj1#

原因是什么

query_str = "Set @null_val = \'\'; "\
    " select @null_val"
erpur_df = pd.read_sql(query_str, con = db)

引发该异常是因为您所做的只是将null\u值设置为“”,然后选择该值 '' -你希望它能给你什么?编辑 read_sql 似乎一次只执行一个查询,由于第一个查询不返回任何行,因此会导致该异常。如果您将它们分成两个调用来读取\u sql,那么它实际上会返回 @null value 在第二次通话中。由于这种行为 read_sql 显然不是一个好办法。我强烈建议你使用我下面的建议之一。
为什么要使用'@'在sql中设置变量?
你可以试着用 .format 字符串格式的样式。
像这样:

query_str = "select ... coalesce(field1, {c}), case(.. then {c})...".format(c=my_const)
pd.read_sql(query_str)

只要记住如果你这样做 my_const 如果是用户输入,则需要手动对其进行清理,以防止sql注入。
另一种可能是使用如下参数的dict:

query_str = "select ... coalesce(field1, %(my_const)s, case(.. then %(my_const)s)..."
pd.read_sql(query_str, params={'my_const': const_value})

但是,这取决于您使用的数据库驱动程序。
从pandas.read\u sql文档:
查看数据库驱动程序文档,了解支持PEP249的paramstyle中描述的五种语法样式中的哪一种。例如,对于psycopg2,使用%(name)s,所以使用params={'name':'value'}

相关问题