处理psycopg2中的重复字段
我正在使用Flask(Python3.4)&psycopg2编写web应用程序来连接到postgres 9.4数据库。
我可以在我的web应用程序中选择用户可以编写自己的查询并使用web应用程序执行它,并在html表中获取输出作为响应。
我使用游标作为conn.cursor(cursor_factory = psycopg2.extras.DictCursor)我不能改变,因为它也被其他部分的web应用程序使用。
我的一位用户像下面这样写了SQL,
SELECT
name || ' - ' || address,
id,
salary || '; ' || id from company;
psycopg2输出(错误) :
?column? id ?column?
text integer (4) text
500.55; 1 1 500.55; 1
500.55; 2 2 500.55; 2
500.55; 3 3 500.55; 3
500.55; 4 4 500.55; 4
999.99; 5 5 999.99; 5
在这里,我得到的结果是错误的,由于重复键/字段名?列? 第二次出现覆盖第一次。
预期产出是:
?column? id ?column?
text integer (4) text
AAA - XY 1 500.55; 1
BBB - ZZ 2 500.55; 2
ABC - YY 3 500.55; 3
ABC - CC 4 500.55; 4
ABC - DD 5 999.99; 5
发送响应的服务器端代码:
# Fetch the column info
if cur.description is not None:
colinfo = [desc for desc in cur.description]
# Any rows?
if cur.rowcount > 0:
result = []
try:
for row in cur:
result.append(dict(row))
except psycopg2.ProgrammingError:
result = None
# response for html table
return Response(
response=json.dumps(colinfo, result),
status=status,
mimetype="text/json"
)
请建议,我怎样才能解决这个最小的代码更改?
同时我也提出了psycopg2的问题,https://github.com/psycopg/psycopg2/issues/454
基本的问题是字典条目必须有唯一的键。 如果将要有多个具有相同名称的列,则不能将列名称用作关键字。 然而,你可以检查,如果有一个重复的列名,使其独特:
# Fetch the column info
if cur.description is not None:
colinfo = [desc for desc in cur.description]
# Any rows?
if cur.rowcount > 0:
result = []
rowdict = {}
colnames = [desc[0] for desc in cur.description]
try:
for row in cur:
rowdict = {}
for x in range(0, len(row)):
# make sure column name is unique, if not append index number
if colnames[x] in rowdict:
rowdict[colnames[x] + "_" + str(x)] = row[x]
else:
rowdict[colnames[x]] = row[x]
result.append(rowdict)
except psycopg2.ProgrammingError:
result = None
# response for html table
return Response(
response=json.dumps(colinfo, result),
status=status,
mimetype="text/json"
)
根据您在客户端所做的操作,您可能还必须更新colinfo以反映所做的任何列名称更改。 如果列名重复,另一个选择是返回明确的错误消息,以便用户可以控制返回的列名称。
它最终是psycopg2中的一个错误,但它只是返回postgres在这种情况下为列名提供的内容。 现在还不清楚它应该做什么。
我假设你已经考虑并处理了与从客户端执行SQL相关的严重信息安全风险。 我并不是想成为传教士,但是这是一个公共论坛,如果其他人想要做这样的事情,我会因为没有提到这个问题而放弃。
链接地址: http://www.djcxy.com/p/60841.html