处理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

上一篇: handle duplicates fields in psycopg2

下一篇: How to install psycopg2 with "pip" on Python?