【问题标题】:exporting data from psql to json formatted wrong将数据从 psql 导出到 json 格式错误
【发布时间】:2021-10-20 13:06:18
【问题描述】:

在我的烧瓶应用程序中,我尝试练习从 psql 表中获取数据并将其放入下拉列表中。我正在使用它来使用来自 here 的查询获取带有 psycopg2 的数据:

def load_authors(self):
    # sql = "SELECT * FROM authors"
    sql = "select array_to_json(array_agg(row_to_json(t))) from (select id, name from authors) t"
    self.curs.execute(sql)
    data = self.curs.fetchall()
    print(data)
    return data

这是我想要格式化为 json 的 psql 数据:

[(1, 'Christopher Paolini'), (2, 'Marie Lu'), (3, 'John Flanagan')]

前面的代码将数据导出到这个:

[([{'id': 1, 'name': 'Christopher Paolini'}, {'id': 2, 'name': 'Marie Lu'}, {'id': 3, 'name': 'John Flanagan'}],)]

它似乎采用了我想要的正确格式的 json:

[{'id': 1, 'name': 'Christopher Paolini'}, {'id': 2, 'name': 'Marie Lu'}, {'id': 3, 'name': 'John Flanagan'}]

然后把它放在另一个列表中?我对此还没有很深入的了解,所以我想知道它为什么会这样做以及如何解决它。我尝试了多个不同的查询,但到目前为止,它们都返回列表中的列表。

【问题讨论】:

    标签: python json psycopg2 psql


    【解决方案1】:

    通常row_to_json 就足够了:

    cur = con.cursor()
    query = '''
        select row_to_json(t) as obj from (
            select id, usage from products where id < 5
        ) t
    '''
    
    cur.execute(query)
    data = cur.fetchall()
    print([x[0] for x in data])
    print([list(x[0].values()) for x in data])
    

    输出:

    [{'id': 2, 'usage': 'shop'}, {'id': 4, 'usage': 'shop'}]
    [[2, 'shop'], [4, 'shop']]
    

    【讨论】:

    • 这给了我一个错误:TypeError: 'NoneType' object is not iterable
    • data 为空?
    • 那是我的错,我的退货声明被注释掉了。您的 print([x[0] for x in data]) 为我提供了我想要的 json 格式,所以我只是使用 str([x[0] for x in data]) 将其分配给我的变量。谢谢!
    【解决方案2】:

    快速回答是使用array_to_json 通常会导致嵌套数组。甚至文档也说明了这一点。

    array_to_json('{{1,5},{99,100}}'::int[])
    

    产量

    [[1,5],[99,100]]
    

    相反,这里有一种更适合您的方法。

    SELECT
      json_build_object(
        'authors',
        json_agg(authors)
      ) authors
    from
      (
        select
          authors.id as id,
          authors.name as name
        from
          authors
      ) authors
    

    这会产生

    {
      "authors": [
        {
          "id": 920,
          "name": "Ryan"
        },
        {
          "id": 3399,
          "name": "John"
        }
      ]
    }
    

    json_build_object 允许您使用交替的键/值对构建自定义对象。像这样:

    json_build_object('foo',1,'bar',2)
    

    产量

    {"foo": 1, "bar": 2}
    

    在这种情况下,我们正在构建一个具有 authors 键和 json_agg(authors) 值的对象,这会将我们的作者查询转换为由以下别名查询返回的行数组。

    绕开大脑有点困难,但它的性能非常好,我推荐使用这种技术快速从数据库中抓取大量 JSON 数据。

    【讨论】:

    • 我确实得到了这个结果,但它嵌套在一个外部数组中: [({'authors': [{'id': 1, 'name': 'Christopher Paolini'}, {' id': 2, 'name': 'Marie Lu'}, {'id': 3, 'name': 'John Flanagan'}]},)] 我不确定在我的所有查询中是什么导致了这个外部数组
    猜你喜欢
    • 1970-01-01
    • 2017-03-07
    • 2014-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多