检查 psycopg2/postgresql 中是否存在 python 值列表
Checking existence of list of python values in psycopg2/postgresql
我有一个 python 值列表和一个包含特定列的 postgresql table。对于 python 列表中的每个元素,我想知道 table 中是否有具有该 ID 的任何行。
例如,假设我有这个 python 列表:
vals = [4, 8, 15, 16, 23, 42]
还有查询:
select my_col from my_table;
给出:
[4, 5, 6, 7, 8]
那么我想要一个返回的查询:
[True, True, False, False, False, False]
我可以遍历列表并为每个值执行一个新的 "select exists",但我想知道是否有一种方法可以在一次调用中完成?
我仅限于 postgresql 9.0
我认为这需要混合使用字符串格式和占位符(因为 vals
中的每个项目需要一个 %s
):
vals = [4, 8, 15, 16, 23, 42]
query = 'select distinct(my_col) from my_table where my_col in ('
query += ', '.join(['%s'] * len(vals))
query += ')'
cursor.execute(query, vals)
theset = {t[0] for t in cursor.fetchall()}
theboollist = [v in theset for v in vals]
这种方法应该保证您发送到数据库的数据量(对于 where ... in
子句)和您从中返回的数据量都是 O(N)
其中 N
等于len(vals)
;我认为从逻辑上讲不可能比 big-O 做得更好。
这个问题更多的是关于 SQL 而不是关于 Python 或 psycopg。我会使用这样的查询:
SELECT my_col = ANY(your_array_here) FROM my_table;
获得结果 "table order" 或:
SELECT A.x = ANY(SELECT my_col FROM my_table)
FROM (SELECT * FROM unnest(your_array_here) x) A;
得到 "vals order" 中的结果。
幸运的是,psycopg 提供了一个默认适配器,可以将 Python 列表转换为 PostgreSQL 数组,代码非常简单:
curs.execute("SELECT my_col = ANY(%s) from my_table", (vals,))
或:
curs.execute("""SELECT A.x = ANY(SELECT my_col FROM my_table)
FROM (SELECT * FROM unnest(%s) x) A""", (vals,))
请注意,绑定变量参数应该是 dict
或元组,并且您想将完整列表绑定到查询中的单个变量,这意味着您应该使用 1 元素元组 ((vals,)
) 而不是尝试直接传递 vals
。
我有一个 python 值列表和一个包含特定列的 postgresql table。对于 python 列表中的每个元素,我想知道 table 中是否有具有该 ID 的任何行。
例如,假设我有这个 python 列表:
vals = [4, 8, 15, 16, 23, 42]
还有查询:
select my_col from my_table;
给出:
[4, 5, 6, 7, 8]
那么我想要一个返回的查询:
[True, True, False, False, False, False]
我可以遍历列表并为每个值执行一个新的 "select exists",但我想知道是否有一种方法可以在一次调用中完成?
我仅限于 postgresql 9.0
我认为这需要混合使用字符串格式和占位符(因为 vals
中的每个项目需要一个 %s
):
vals = [4, 8, 15, 16, 23, 42]
query = 'select distinct(my_col) from my_table where my_col in ('
query += ', '.join(['%s'] * len(vals))
query += ')'
cursor.execute(query, vals)
theset = {t[0] for t in cursor.fetchall()}
theboollist = [v in theset for v in vals]
这种方法应该保证您发送到数据库的数据量(对于 where ... in
子句)和您从中返回的数据量都是 O(N)
其中 N
等于len(vals)
;我认为从逻辑上讲不可能比 big-O 做得更好。
这个问题更多的是关于 SQL 而不是关于 Python 或 psycopg。我会使用这样的查询:
SELECT my_col = ANY(your_array_here) FROM my_table;
获得结果 "table order" 或:
SELECT A.x = ANY(SELECT my_col FROM my_table)
FROM (SELECT * FROM unnest(your_array_here) x) A;
得到 "vals order" 中的结果。
幸运的是,psycopg 提供了一个默认适配器,可以将 Python 列表转换为 PostgreSQL 数组,代码非常简单:
curs.execute("SELECT my_col = ANY(%s) from my_table", (vals,))
或:
curs.execute("""SELECT A.x = ANY(SELECT my_col FROM my_table)
FROM (SELECT * FROM unnest(%s) x) A""", (vals,))
请注意,绑定变量参数应该是 dict
或元组,并且您想将完整列表绑定到查询中的单个变量,这意味着您应该使用 1 元素元组 ((vals,)
) 而不是尝试直接传递 vals
。