2017-06-05 135 views
1

我正在尋找一種非顯式的方式來解析JSON列表(即[] {}內的項目)到sqlite數據庫中。使用Python將多個json項目解析到SQLite數據庫中

具體來說,我被困在地步,我想說

INSERT into MYTABLE (col 1, col2, ...) this datarow in this jsondata 

我覺得應該有一個方法來抽象的東西,例如,上面的線幾乎是什麼需要。我的數據是一個JSON列表,其中包含多個JSON 字典。每個字典都有十幾個鍵值對。沒有嵌套。

{"object_id":3   ,"name":"rsid"   ,"column_id":1 
,"system_type_id":127 ,"user_type_id":127  ,"max_length":8 
,"precision":19   ,"scale":0    ,"collation_name":null 
,"is_nullable":false ,"is_ansi_padded":false ,"is_rowguidcol":false 
,"is_identity":false ,"is_computed":false ,"is_filestream":false 
,"is_replicated":false ,"is_non_sql_subscribed":false 
,"is_merge_published":false      ,"is_dts_replicated":false 
,"is_xml_document":false      ,"xml_collection_id":0 
,"default_object_id":0 ,"rule_object_id":0  ,"is_sparse":false 
,"is_column_set":false} 

json列表[{k1:v1a, k2:v2a}, {k1:v1b,k2:v2b},...]中的每一個itesm都將具有完全相同的KEY名稱。我已經將這些作爲我sqlite數據庫中列的名稱。 VALUES將會有所不同。因此,通過將每個KEY/COLUMN的VALUES賦值給該項目的該行來填充表格。

k1 | k2 | k3 | ... | km 
v1a | v2a | v3a | ... | vma 
v1b | v2b | v3b | ... | vmb 
... 
v1n | v2n | v3n | ... | vmn 

在SQL中,插入語句不需要按照與數據庫列完全相同的順序編寫。這是因爲您在INSERT聲明中指定了要插入的列(以及順序)。這似乎是JSON的完美選擇,其中JSON列表中的每個行的行/item都包含其列名(鍵)。因此,我想要一條聲明,指出「給定這一行JSON,通過將JSON密鑰名稱與SQL表列名稱協調一致,將其所有數據插入到SQL表中」。這是我的意思是非明確的。

import json 

r3 = some data file you read and close 
r4 = json.loads(r3) 
# let's dump this into SQLite 

import sqlite3 

the_database = sqlite3.connect("sys_col_database.sqlite") 
the_cursor = the_database.cursor() 

row_keys = r4[0].keys() 
# all of the key are below for reference. 25 total keys. 
''' 
'is_merge_published', 'rule_object_id', 'system_type_id', 
'is_xml_document',  'user_type_id',  'is_ansi_padded', 
'column_id',   'is_column_set', 'scale', 
'is_dts_replicated', 'object_id',  'xml_collection_id', 
'max_length',   'collation_name', 'default_object_id', 
'is_rowguidcol',  'precision',  'is_computed', 
'is_sparse',   'is_filestream', 'name', 
'is_nullable',   'is_identity',  'is_replicated', 
'is_non_sql_subscribed' 
''' 

sys_col_table_statement = """create table sysColumns (
    is_merge_published text, 
    rule_object_id integer, 
    system_type_id integer, 
    is_xml_document text, 
    user_type_id integer, 
    is_ansi_padded text, 
    column_id integer, 
    is_column_set text, 
    scale integer, 
    is_dts_replicated text, 
    object_id integer, 
    xml_collection_id integer, 
    max_length integer, 
    collation_name text, 
    default_object_id integer, 
    is_rowguidcol text, 
    precision integer, 
    is_computed text, 
    is_sparse text, 
    is_filestream text, 
    name text, 
    is_nullable text, 
    is_identity text, 
    is_replicated text, 
    is_non_sql_subscribed text 
    ) 
""" 

the_cursor.execute(sys_col_table_statement) 

insert_statement = """insert into sysColumns values (
{0},{1},{2},{3},{4}, 
{5},{6},{7},{8},{9}, 
{10},{11},{12},{13},{14}, 
{15},{16},{17},{18},{19}, 
{20},{21},{22},{23},{24})""".format(*r4[0].keys()) 

這就是我卡住了。 insert_statement是字符串的構造,將是execute d。現在我需要執行它,但從r4中的每個JSON項目提供正確的數據。我不知道該怎麼寫。

回答

1

這裏有兩個選項。我也一步加載了JSON數據。

#python 3.4.3 

import json 
import sqlite3 

with open("data.json",'r') as f: 
    r4 = json.load(f) 

the_database = sqlite3.connect("sys_col_database.sqlite") 
the_cursor = the_database.cursor() 

row_keys = list(r4[0].keys()) 
# all of the key are below for reference. 25 total keys. 
''' 
'is_merge_published', 'rule_object_id', 'system_type_id', 
'is_xml_document',  'user_type_id',  'is_ansi_padded', 
'column_id',   'is_column_set', 'scale', 
'is_dts_replicated', 'object_id',  'xml_collection_id', 
'max_length',   'collation_name', 'default_object_id', 
'is_rowguidcol',  'precision',  'is_computed', 
'is_sparse',   'is_filestream', 'name', 
'is_nullable',   'is_identity',  'is_replicated', 
'is_non_sql_subscribed' 
''' 

sys_col_table_statement = """create table sysColumns (
is_merge_published text, 
rule_object_id integer, 
system_type_id integer, 
is_xml_document text, 
user_type_id integer, 
is_ansi_padded text, 
column_id integer, 
is_column_set text, 
scale integer, 
is_dts_replicated text, 
object_id integer, 
xml_collection_id integer, 
max_length integer, 
collation_name text, 
default_object_id integer, 
is_rowguidcol text, 
precision integer, 
is_computed text, 
is_sparse text, 
is_filestream text, 
name text, 
is_nullable text, 
is_identity text, 
is_replicated text, 
is_non_sql_subscribed text 
) 
""" 
# method 1 
# create a string with the keys prepopulated 
prepared_insert_statement = """insert into sysColumns (\ 
{0}, {1}, {2}, {3}, {4}, \ 
{5}, {6}, {7}, {8}, {9}, \ 
{10}, {11}, {12}, {13}, {14}, \ 
{15}, {16}, {17}, {18}, {19}, \ 
{20}, {21}, {22}, {23}, {24}) values (\ 
'{{{0}}}', '{{{1}}}', '{{{2}}}', '{{{3}}}', '{{{4}}}', \ 
'{{{5}}}', '{{{6}}}', '{{{7}}}', '{{{8}}}', '{{{9}}}', \ 
'{{{10}}}', '{{{11}}}', '{{{12}}}', '{{{13}}}', '{{{14}}}', \ 
'{{{15}}}', '{{{16}}}', '{{{17}}}', '{{{18}}}', '{{{19}}}', \ 
'{{{20}}}', '{{{21}}}', '{{{22}}}', '{{{23}}}', '{{{24}}}'\ 
)""".format(*r4[0].keys()) 

# unpack the dictionary to extract the values 
insert_statement = prepared_insert_statement.format(**r4[0]) 

# method 2 
# get the keys and values in one step 
r4_0_items = list(r4[0].items()) 
insert_statement2 = """insert into sysColumns (\ 
{0[0]}, {1[0]}, {2[0]}, {3[0]}, {4[0]}, \ 
{5[0]}, {6[0]}, {7[0]}, {8[0]}, {9[0]}, \ 
{10[0]}, {11[0]}, {12[0]}, {13[0]}, {14[0]}, \ 
{15[0]}, {16[0]}, {17[0]}, {18[0]}, {19[0]}, \ 
{20[0]}, {21[0]}, {22[0]}, {23[0]}, {24[0]}) values (\ 
'{0[1]}', '{1[1]}', '{2[1]}', '{3[1]}', '{4[1]}', \ 
'{5[1]}', '{6[1]}', '{7[1]}', '{8[1]}', '{9[1]}', \ 
'{10[1]}', '{11[1]}', '{12[1]}', '{13[1]}', '{14[1]}', \ 
'{15[1]}', '{16[1]}', '{17[1]}', '{18[1]}', '{19[1]}', \ 
'{20[1]}', '{21[1]}', '{22[1]}', '{23[1]}', '{24[1]}'\ 
)""".format(*r4_0_items) 


the_cursor.execute(sys_col_table_statement) 
#the_cursor.execute(insert_statement) 
the_cursor.execute(insert_statement2) 
the_database.commit() 

參考:
unpack dictionary
string formatting examples

+0

,我在外面今天測試此。謝謝。我認爲方法2對我目前的水平更有意義。 – VISQL

+0

再次感謝。我意識到我的INSERT語句格式不正確。你的榜樣幫助我克服了障礙。此外,還注意到了更深層次的東西 - 我的一些「值」應該在INSERT語句中不加引號。最後,我個人不喜歡「With」語句,因爲它縮進了它創建的變量,所以目前還不清楚變量現在是全局的。你是正確的使用它,只是讓我的頭旋轉了一下。 – VISQL

相關問題