【问题标题】:Converting JSON into Python Dict with Postgresql data imported with SQLAlchemy使用 SQLAlchemy 导入的 Postgresql 数据将 JSON 转换为 Python Dict
【发布时间】:2015-11-30 23:04:56
【问题描述】:

关于将 JSON 字符串转换为 Python 数据字典以便在 Pandas 中进行分析,我在这里遇到了一个棘手的问题。我已经阅读了很多关于此的其他问题,但似乎没有一个适合我的情况。

以前,我只是使用 CSV(和 Pandas 的 read_csv 函数)来执行我的分析,但现在我已经转向直接从 PostgreSQL 中提取数据。

我使用 SQLAlchemy 连接到我的引擎并运行我的查询没有问题。我的整个脚本的运行方式与我从 CSV 中提取数据时的运行方式相同。也就是说,直到它到达我试图将其中一列(即下面示例文本中的“配置”列)从 JSON 转换为 Python 字典的部分。将其转换为 dict 的最终目标是能够计算“config”列中“options”字段下的响应数。

df = pd.read_sql_query('SELECT questions.id, config from questions ', engine)

df = df['config'].apply(json.loads)

df = pd.DataFrame(df.tolist())

df['num_options'] = np.array([len(row) for row in df.options])

当我运行它时,我收到错误“TypeError:预期的字符串或缓冲区”。我尝试将“配置”列中的数据从对象转换为字符串,但这并没有成功(我收到另一个错误,例如“ValueError:期望属性名称......”)。

如果有帮助,这里是来自“配置”列中一个单元格的数据片段(代码应该为这个片段返回结果“6”,因为有 6 个选项):

{"graph_by":"series","options":["Strongbow Case Card/Price Card","Strongbow Case Stacker","Strongbow Pole Topper","Strongbow Base wrap","Other Strongbow POS","None"]}

我的猜测是,当 SQLAlchemy 从数据库中提取 JSON 字符串时,它对 JSON 字符串做了一些奇怪的事情?当我只是从数据库中提取 CSV 时不会发生什么事情?

【问题讨论】:

    标签: python json postgresql dictionary sqlalchemy


    【解决方案1】:

    在最近的Psycopg 版本中,Postgresql json(b) 对 Python 的适应是透明的。 Psycopg 是 Postgresql 的默认 SQLAlchemy 驱动程序

    df = df['config']['options']
    

    来自Psycopg 手册:

    Psycopg 可以使 Python 对象适应 PostgreSQL json 和 jsonb 类型。对于 PostgreSQL 9.2 及以下版本,可以开箱即用地进行适配。要在以前的数据库版本中使用 JSON 数据(使用 9.1 json 扩展,但即使您想将文本字段转换为 JSON),您也可以使用 register_json() 函数。

    【讨论】:

    • 很抱歉延迟回复您,但效果很好,非常感谢分享!
    【解决方案2】:

    只需sqlalchemy查询:

    q = session.query(
        Question.id,
        func.jsonb_array_length(Question.config["options"]).label("len")
    )
    

    sql和pandas'read_sql_query

    sql = """\
    SELECT  questions.id,
            jsonb_array_length(questions.config -> 'options') as len
    FROM    questions
    """
    df = pd.read_sql_query(sql, engine)
    

    结合两者(我最喜欢的):

    # take `q` from the above
    df = pd.read_sql(q.statement, q.session.bind)
    

    【讨论】:

      猜你喜欢
      • 2019-10-08
      • 1970-01-01
      • 1970-01-01
      • 2013-09-21
      • 2011-05-30
      • 1970-01-01
      • 2018-01-08
      相关资源
      最近更新 更多