我使用psycopg2向postgresql查询提供一些枚举数据。这些数据需要连接到我用来返回我想要的数据的表,这样我就可以按正确的顺序获取它们。似乎psycopg2只允许将数据提供为数组或单个值的括号。以下是一个查询尝试的示例:
SELECT table_a.foo, table_b.bar
FROM table_a
JOIN table_b USING(id)
JOIN unnest(ARRAY[(0,34523), (1, 3453)]) AS baz (index, id) USING (id)
ORDER BY baz.index ASC
正如您所看到的,我使用数组来选择我想要的ID,但也提供另一列来排序行,但我无法使数据表现为连接表。在此示例中,我收到以下错误:返回函数需要列定义列表"记录"
而不是ARRAY,数据可以提供为:((0,34523), (1, 3453))
除非psycopg2允许VALUES列表,例如:VALUES (0,34523), (1, 3453)
?
我正在使用postgresql 9.1.13
答案 0 :(得分:0)
我确实找到了解决方案,其中包括在部分中构建查询字符串:
enumerated_ids = ','.join(self.cur.mogrify("(%s, %s)", x) for x in enumerate(ids))
self.execute("""
SELECT table_a.foo, table_b.bar
FROM table_a
JOIN table_b USING(id)
JOIN (VALUES """+ enumerated_ids +""") AS baz (index, id) USING (id)
ORDER BY baz.index ASC
""", ())
答案 1 :(得分:0)
重要提示:接受的答案非常危险,不应使用。
http://initd.org/psycopg/docs/usage.html#passing-parameters-to-sql-queries州:
如果包含要发送到数据库的数据的变量来自不受信任的来源(例如网站上发布的表单),攻击者可能很容易制作出格式错误的字符串,要么获取对未经授权的数据的访问权限,要么执行破坏性操作数据库。这种形式的攻击称为SQL注入,并且已知是对数据库服务器的最广泛的攻击形式之一。在继续之前,请将此页面作为备忘录打印并挂在桌面上。
Psycopg可以自动将Python对象与SQL文字进行转换:使用此功能,您的代码将更加健壮和可靠。我们必须强调这一点:
警告永远不要,永远不要使用Python字符串连接(+)或字符串参数插值(%)将变量传递给SQL查询字符串。甚至在枪口下也没有。
但是,您可以定义自己的采用者:
class Values(object):
def __init__(self, value):
self.storage = value
def adapt_values(value):
return AsIs("(VALUES(" + ", ".join(map(lambda x: str(x), value.storage)) + ")")
register_adapter(Values, adapt_values)
cur.execute("SELECT X, Y FROM Table JOIN %s V(A, B) ON A = X AND Y = B", [Values(my_values)])
文档:http://initd.org/psycopg/docs/advanced.html#adapting-new-python-types-to-sql-syntax