在 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列 - channel,report_id和report_data -
我想将来自JSON的'account_id'插入到频道列中,将'id'插入到report_id列中,将其余的JSON全部插入到report_data列中。
有人可以告诉我如何做到这一点吗?
答案 0 :(得分:3)
以下是在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()
更改:
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()
更改
您可以清理它并根据需要进行修改。试一试,让我知道。
答案 1 :(得分:1)
上面的答案有些复杂。
在psycopg2 office document中,有一个类类型调用psycopg2.extras.Json
,它是一个ISQLQuote包装器,用于使Python对象适应json数据类型。
import psycopg2
import logging
from psycopg2.extras import Json
conn = psycopg2.connect(dbname=" ",
user=" ",
password=" ",
host="127.0.0.1",
port="5432")
data2 = {
'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
}
item = {
'channel': data2['account_id'],
'report_id': data2['id'],
'report_data': Json(dict([(k, v) for k, v in data2.items() if k not in ['account_id', 'id']]))
}
def sql_insert(tableName, data_dict):
'''
INSERT INTO onetable (channel, report_id, report_data)
VALUES (%(channel)s, %(report_id)s, %(report_data)s );
'''
sql = '''
INSERT INTO %s (%s)
VALUES (%%(%s)s );
''' % (tableName, ', '.join(data_dict), ')s, %('.join(data_dict))
return sql
tableName = 'onetable'
sql = sql_insert(tableName, item)
try:
with conn.cursor() as cur:
cur.execute(sql, item)
conn.commit()
except Exception as e:
logging.debug(e)
conn.rollback()
finally:
conn.close()
答案 2 :(得分:0)
您可以使用jsonb数据类型进行插入。 请参阅下面的链接。 https://www.compose.com/articles/faster-operations-with-the-jsonb-data-type-in-postgresql/