用于创建查询的psycopg2变量格式

时间:2015-01-23 22:59:46

标签: python postgresql psycopg2

这不是那么相关,所以我只是对以下内容感到好奇(Python 2.7):

我刚刚开始使用psycopg并阅读文档,他们总是使用字符串(%s)和元组将值传递给查询。

  

变量占位符必须始终为%s

因此,请考虑以下示例 -

在名为' test'的表格中使用字段value_1(varchar)和value_2(int)将查询创建为:

value_1 = "test"
value_2 = "100"
cur.execute("INSERT INTO test (value_1,value_2) VALUES (%s,%s)",\
           (value_1,value_2))

我的问题是,使用“格式”是不是一种不好的做法,甚至是有问题的。方法改为(如下):

cur.execute("INSERT INTO test (value_1,value_2) VALUES ('{value1}',{value2})".\
           format(value1=value_1,value2=value_2))

根据您的经验,您说什么,这真的很危险或有问题吗?

3 个答案:

答案 0 :(得分:5)

电话

cur.execute("INSERT INTO test (value_1,value_2) VALUES (%s,%s)",\
           (value_1,value_2))

有一个字符串参数和一个附加参数,它是替换值的元组。 这允许psycopg2插值,并且比简单的字符串插值更安全。

usage docs for psycopg2

  

♯传递数据以填充查询占位符并让Psycopg执行

     

♯正确的转换(不再进行SQL注入!)

     

&GT;&GT;&GT; cur.execute(&#34; INSERT INTO test(num,data)VALUES(%s,%s)&#34;,...(100,&#34; abc&#39; def&#34;))< / p>

在通话中

cur.execute("INSERT INTO test (value_1,value_2) VALUES ('{value1}',{value2})".\
           format(value1=value_1,value2=value_2))

是自己插值,只是将结果字符串传递给游标执行方法。

简单插值易受SQL注入的影响。你可能最好使用第一种形式。

您应该始终考虑"Little Bobby Tables"

答案 1 :(得分:1)

在阅读了一些文档和资源并自行测试后,直截了当。 简单的回答:这是不安全的。不仅适用于psycopg2,也适用于任何数据库模块(至少对于我测试的那些)。 将此与psycopg2相关联,使用(%s),(变量)允许psycopg2自动转义这些变量以防止这样的混乱。

我试图找出它可以造成的小麻烦:

cur.execute("INSERT INTO test (value_1,value_2) VALUES ('{value1}','{value2}')".\
format(value1=value_1,value2='1); drop table test; --killer instinct'))

就是这样,adiós测试表:-P

答案 2 :(得分:1)

是的,Psycopg2对所有类型都使用%s,psycopg2将参数转换为字符串表示形式并在查询中使用它

INSERT INTO test (value_1,value_2) VALUES('test','100');

有时您可能需要将某些值强制转换为适当的类型。

 cur.execute("""INSERT INTO test (value_1,value_2) 
       VALUES (%s,%s::integer)""",
       (value_1,value_2))

你提出的方法是非常糟糕的做法,你已经为value_1和value_2的几个可能的值注入了sql。例如:

 value_1="',0); rollback; drop table test ; --"