我想通过python构建一个动态插入查询。数据源是具有多维度的数组。该数组看起来像这样:
[<insight>{
"action":[
{
"name":"col1",
"value":"20",
},
{
"name":"col2",
"value":"30",
},...
],
"call":"a"
}]
问题是“动作”不是排序,大部分时间只包含一些列。所以第二个见解可能就是这样:
[<insight>{
"action":[
{
"name":"col3",
"value":"10",
},
{
"name":"col2",
"value":"50",
},...
],
"call":"b"
}]
总之,我有30列。有没有一种有效的方法来构建插入查询?结果可能如下:
call | col1 | col2 | col3
-----------------------
a | 20 | 30 | 0
b | 0 | 50 | 10
我的尝试有效,但非常密集。
sql="INSERT INTO t_x ('col1','col2','col3') VALUES (("
cols=["col1","col2","col3"]
for insight in insights:
for i in range(len(cols)):
for j in range(insight["action"]):
if cols[i]==insight["action"][j]["name"]:
sql += insight["action"][j]["nvalue"] + ","
break
if j==len(insight["action"][j]["name"]):
sql += "0,"
sql = sql[:-1] + "),"
sql = sql[:-1] + ")"
核心思想是我有静态INSERT前置字符串(插入t_x (COL1,COL2,COL3) ...) 其余的我需要遍历所有操作并将名称与所有列名进行比较。结果如下:
sql =“INSERT INTO t_x('col1','col2','col3')VALUES (( '20', '30', '0'),( '0', '50', '10'))“
如果我能用直接的语句替换搜索循环,那将是很好的:
“INSERT INTO t_x('col1','col2','col3')VALUES ((洞察[ '动作'] [j]的[ 'COL1'],洞察力[ '动作'] [j]的[ 'COL2'] ...
知道我怎样才能更好地处理这种格式?我没有多少经验
答案 0 :(得分:1)
我试图解释你的json并将其分配给变量insights
:
insights = [{
"action":[
{
"name":"col1",
"value":"20",
},
{
"name":"col2",
"value":"30",
}
],
"call":"a"
},
{
"action":[
{
"name":"col3",
"value":"10",
},
{
"name":"col2",
"value":"50",
}
],
"call":"b"
}]
创建一个辅助函数,使数据结构保存列值:
def empty_columns(n):
return {'col%d' % i: 0 for i in range(1, n+1)}
接下来循环通过json填充参数行(使用名称而不是整数索引,只有两个for循环级别,以及一些空行使代码有空间呼吸):
def get_query_params(insights):
n = 5 # number of columns, adapt to your needs
res = []
for action in insights:
cur = [action['call']] + [0] * n
cols = empty_columns(5)
for colval in action['action']:
cols[colval['name']] = colval['value']
for i in range(1, n+1): # fill the parameter array from cols
cur[i] = cols['col%d' % i]
res.append(cur)
return res
您现在可以验证参数列表是否为列表:
params = get_query_params(insights)
print params
输出将是(为了清晰起见,我添加了换行符):
[['a', '20', '30', 0, 0, 0],
['b', 0, '50', '10', 0, 0]]
最后,从您的连接中抓取一个游标(cn
),然后使用executemany
方法立即传递所有参数:
c = cn.cursor()
c.executemany("""
insert in to t_x (col1, col2, col3, col4, col5)
values (%s, %s, %s, %s, %s)
""", params)
这称为参数化调用,%s
是占位符(MySQL使用%s
其他数据库可以使用例如?
,检查您的数据库库)。不要将此与字符串插值混淆。