以下是在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值作为文本,然后将它们强制转换为整数。
更新的更新:我按照您的代码格式进行了格式化,并在下面注明了我所做的更改:
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)
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"
data2 = {"id": 4573457, "account_id": 456, "address": "15 Millers Rd, WA"}
data2_json = json.dumps(data2)
sql_params = (data2_json,)
calldb(conn, sql_cmd, sql_params)
conn.commit()
变更
- 添加了sql_params变量到calldb()函数,以传递sql参数
- 添加了连接参数行以连接到数据库(不确定你在你的代码中是如何处理的)
- 将data2字典数据类型转换为JSON数据类型(这与之前出现的“无法调整”字典错误相关)
- 建议:在完成后,应该关闭DB游标和连接,不确定您是否这样做
您可以根据需要进行清理和修改。试试并让我知道。
except Exception as e: print('错误', 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
, (data2,) )"""calldb(conn, sql_cmd)conn.commit() - Paul