将JSON插入Postgres 9.5

保罗

Python 3.6中,我有一个变量' data2 ',其中包含一个如下所示的JSON

{
    'id': 4573457, 'account_id': 456, 'address': '15 Millers Rd, WA', 
    'category_id': 4565, 'description': None, 'is_anonymous': False, 
    'iso_created_at': '2017-11-21T14:08:54+11:00', 
    'location': {
        'latitude': -56.564848493, 'longitude': 345.5948493}, 
    'report_state_id': 45655, 'report_state_name': 'ALL PICKED', 
    'title': 'South', 'user_id': 44555, 'user_short_name': 'Todd G.', 
    'users_alerted_count': 0, 'users_opened_count': 6, 'shape_id': 56
}

我想写一个INSERT语句到这个数据插入到我已经在创建表的Postgres 9.5,该表有3列-通道,REPORT_ID和report_data -

我想将JSON中的'account_id'插入channel列,将'id'插入report_id列,并将JSON的其余部分全部插入report_data列。

有人可以告诉我我该怎么做吗?

馄饨

这是在Postgres中提取JSON值的基本方法:

  data2->'account_id' AS channel

因此,您的执行SQL应该是这样的:

cursor.execute("
    INSERT INTO MyTable (channel, report_id, report_data)
    SELECT 
      src.MyJSON->'account_id',
      src.MyJSON->'id',
      src.MyJSON
    FROM (
      SELECT %s AS MyJSON
    ) src
  ",
  (data2,)
)

如果您想在将其余的JSON插入report_data字段之前删除account_id / id键,则可以创建第二个“ data2”变量(例如,“ data2_final”),并将其作为参数传递给您的SQL,让我知道它如何为您工作。

更新

CREATE TABLE Mytable (
  channel INTEGER, 
  report_id INTEGER, 
  report_data JSONB
);

cursor.execute("
    INSERT INTO MyTable (channel, report_id, report_data)
    SELECT 
      CAST(src.MyJSON->>'account_id' AS INTEGER),
      CAST(src.MyJSON->>'id' AS INTEGER),
      src.MyJSON
    FROM (
      SELECT CAST(%s AS JSONB) AS MyJSON
    ) src
  ",
  (data2,)
)

http://www.sqlfiddle.com/#!17/fb3af/1

我更新了提取内容以将JSON值返回为文本,然后将其强制转换为INTEGER。

更新的更新我理解了我在下面所做的更改,从而在下面格式化了您的代码:

def calldb( db, sql_cmd): 
    try: 
        cur = db.cursor() 
        cur.execute(sql_cmd, (data2,)) 
        return 
    except Exception as e: 
        print ('Error ', e ) 
        raise 

sql_cmd=" INSERT INTO MyTable (channel, report_id, report_data) SELECT CAST(src.MyJSON->>'account_id' AS INTEGER), CAST(src.MyJSON->>'id' AS INTEGER), src.MyJSON FROM ( SELECT CAST(%s AS JSONB) AS MyJSON ) src" 
calldb(conn, sql_cmd) 
conn.commit()

变化

  • 在sql_cmd的开头和结尾处删除了多余的双引号
  • 在查询中的“ src”之后添加了双引号
  • 将(data2,)元组移至cur.execute()调用

execute()函数的工作方式是,将要执行的SQL字符串(即sql_cmd)作为第一个参数传递给它。字符串中的%s项目是参数化值的占位符。作为第二个参数,您传递一个包含参数值(即(data2,))的数组/元组。

手指交叉:)

更新的更新的更新
这里是工作代码(从您提供的内容略作修改的版本):

import psycopg2
import json

def calldb(db, sql_cmd, sql_params): 
    try: 
        cur = db.cursor()
        cur.execute(sql_cmd, sql_params)
        return
    except Exception as e: 
        print ('Error ', e ) 
        raise 

params = {
  "host":"DB_HOSTNAME",
  "database":"DB_NAME",
  "user":"USERNAME",
  "password":"PASSWORD"
}

conn = psycopg2.connect(**params)

# Prepare SQL
sql_cmd = "INSERT INTO MyTable (channel, report_id, report_data) SELECT CAST(src.MyJSON->>'account_id' AS INTEGER), CAST(src.MyJSON->>'id' AS INTEGER), src.MyJSON FROM ( SELECT CAST(%s AS JSONB) AS MyJSON ) src" 

# Convert dictionary to native JSON data type
data2 = {"id": 4573457, "account_id": 456, "address": "15 Millers Rd, WA"}
data2_json = json.dumps(data2)

sql_params = (data2_json,)

# Execute SQL
calldb(conn, sql_cmd, sql_params) 
conn.commit()

变化

  • 将sql_params变量添加到calldb()以传递sql参数
  • 添加了连接参数行以连接到数据库(不确定您在数据库中的工作方式)
  • 将data2字典数据类型转换为JSON数据类型(这与您为什么收到先前的“无法适应dict”错误有关)
  • 建议:不确定是否执行此操作,但是在完成处理之后,还应该关闭数据库游标和连接

您可以清理它并根据需要进行修改。试试看,让我知道。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

重新排列 PHP 数组,将 1、2、3、4、5、6、7、8、9 重新排序为 1、4、7、2、5、8、3、6、9

将数组的元素添加为a [0],a [1] + a [2],a [3] + a [4] + a [5],a [6] + a [7] + a [8] + a [9] ...等等

如何在Postgres 9.x中插入now()+ INTERVAL

将表插入IF计数(*)<5

安装DBLink for Postgres 9

Python:将1,2,3-7,8,9,10变成这样的字符串1,2,3,4,5,6,7,8,9,10

我需要弹簧5的Java 9?

Nexus 5的9个补丁问题

查询以将json对象数组插入postgres

将Cronjob设置为从9:30 am到4:00 pm每5分钟运行一次

将字符串“2022 年 5 月 11 日上午 9:16”转换为时间戳

将数组元素(例如4-10)更改为管道分隔列表(例如4 | 5 | 6 | 7 | 8 | 9 | 10)

如何将<!-[if lt IE 9]>标记嵌入Blaze.Html5生成的HTML中?

JSON解析内容,结果不可读,例如““ \ U5b9d \ U4e30”“

在插入$ i后将$ 5加到$ i

将 .json 文件数据加载到 Postgres for Rails 5 API

Debian 9:未安装php5软件包

如何在 android RatingBar 上将“9/10”变成“4.5/5”?

Spring 5的反应功能支持Java 9 Flow API吗?

使用JUnit 5和Java 9没有Maven的或摇篮

iOS9导致iPhone 5优化丢失

如何使用休眠验证器检查5或9的长度?

为 Kentico 9+ 寻找 HTML 5 CMS 表单控件

Xcode 9 beta4 / 5:无法安装此应用

Xcode 9 Beta 5无法保存已编辑的.daes

在Cloud 9上运行ASP.NET 5

iOS 9 beta 5更新的UITableView为空

iOS 9 Beta 5上的UIFont系列为空

Angular 9 Ionic 5 httpclient发布发送空数组