简体   繁体   English

用于解析JSON中的数组以插入到SQL表中的函数

[英]Function to Parse Arrays in JSON to Insert Into a SQL Table

Trying to take a web API's JSON response and populate a SQL database with the results. 尝试获取Web API的JSON响应并使用结果填充SQL数据库。

Part of the JSON response has this array: JSON响应的一部分具有以下数组:

"MediaLinks": [
            {
                "MediaType": "Datasheets",
                "SmallPhoto": "",
                "Thumbnail": "",
                "Title": "SN54HC374, SN74HC374",
                "Url": "http://www.ti.com/general/docs/suppproductinfo.tsp?distId=10&gotoUrl=http%3A%2F%2Fwww.ti.com%2Flit%2Fgpn%2Fsn74hc374"
            },
            {
                "MediaType": "Product Photos",
                "SmallPhoto": "http://media.digikey.com/photos/Texas%20Instr%20Photos/296-20-DIP_sml.jpg",
                "Thumbnail": "http://media.digikey.com/photos/Texas%20Instr%20Photos/296-20-DIP_tmb.jpg",
                "Title": "20-DIP,R-PDIP-Txx",
                "Url": "http://media.digikey.com/photos/Texas%20Instr%20Photos/296-20-DIP.jpg"
            },
            {
                "MediaType": "Featured Product",
                "SmallPhoto": "",
                "Thumbnail": "",
                "Title": "Logic Solutions",
                "Url": "https://www.digikey.com/en/product-highlight/t/texas-instruments/logic-solutions "
            },
            {
                "MediaType": "Featured Product",
                "SmallPhoto": "",
                "Thumbnail": "",
                "Title": "Analog Solutions",
                "Url": "https://www.digikey.com/en/product-highlight/t/texas-instruments/analog-solutions "
            },
            {
                "MediaType": "PCN Design/Specification",
                "SmallPhoto": "",
                "Thumbnail": "",
                "Title": "Copper Bond Wire Revision A 04/Dec/2013",
                "Url": "http://media.digikey.com/pdf/PCNs/Texas%20Instruments/PCN20120223003A_Copper-wire.pdf"
            },
            {
                "MediaType": "PCN Design/Specification",
                "SmallPhoto": "",
                "Thumbnail": "",
                "Title": "Material Set 30/Mar/2017",
                "Url": "http://media.digikey.com/pdf/PCNs/Texas%20Instruments/PCN20170310000.pdf"
            }
        ],

For testing I've issued the request and then written the response to a file and I'm experimenting with this file to come up with the correct code 为了进行测试,我发出了请求,然后将响应写入文件中,并且我正在尝试使用该文件以提供正确的代码

conn.request("POST", "/services/partsearch/v2/partdetails", json.dumps(payload), headers)

res = conn.getresponse()
data = res.read()

data_return = json.loads(data)
print(json.dumps(data_return, indent=4))

with open(y["DigiKeyPartNumber"]+".json", "w") as write_file:
    json.dump(data_return, write_file, indent=4, sort_keys=True)
write_file.close()

Then in my test code I've tried this: 然后在我的测试代码中,我尝试了以下方法:

import json

with open(r"C:\Users\george\OneDrive\Documents\296-1592-5-ND.json") as json_file:
    data = json.load(json_file)

values = ""
placeholder = '?'
thelist = []
thelist = list(data['PartDetails']['MediaLinks'])
print(type(thelist))
#print(thelist)

placeholders = ', '.join(placeholder for unused in (data['PartDetails']['MediaLinks']))
query = 'INSERT INTO thetable VALUES(%s)' % placeholders
print(query)

But this just produces the following output: 但这只会产生以下输出:

<class 'list'>
INSERT INTO thetable VALUES(?, ?, ?, ?, ?, ?)

For reference this creates what I think will work except for the trailing comma: 作为参考,这创建了我认为除尾部逗号之外将起作用的内容:

if len(data['PartDetails']['MediaLinks']):
    print('The length is: ' + str(len(data['PartDetails']['MediaLinks'])))
    #print(type(data['PartDetails']['MediaLinks']))
    for mediadata in data['PartDetails']['MediaLinks']:
        #print(mediadata)
        for element in mediadata:
            #print(element + ' is "' + mediadata[element] + '"')
            values += '"' + mediadata[element] + '", '
    #print(list(data['PartDetails']['MediaLinks'][1]))
        print(values + "\n")
        values = ""
else:
    print('It is empty')

Which produces this: 产生此:

The length is: 6
"Datasheets", "", "", "SN54HC374, SN74HC374", "http://www.ti.com/general/docs/suppproductinfo.tsp?distId=10&gotoUrl=http%3A%2F%2Fwww.ti.com%2Flit%2Fgpn%2Fsn74hc374",

"Product Photos", "http://media.digikey.com/photos/Texas%20Instr%20Photos/296-20-DIP_sml.jpg", "http://media.digikey.com/photos/Texas%20Instr%20Photos/296-20-DIP_tmb.jpg", "20-DIP,R-PDIP-Txx", "http://media.digikey.com/photos/Texas%20Instr%20Photos/296-20-DIP.jpg",

"Featured Product", "", "", "Logic Solutions", "https://www.digikey.com/en/product-highlight/t/texas-instruments/logic-solutions ",

"Featured Product", "", "", "Analog Solutions", "https://www.digikey.com/en/product-highlight/t/texas-instruments/analog-solutions ",

"PCN Design/Specification", "", "", "Copper Bond Wire Revision A 04/Dec/2013", "http://media.digikey.com/pdf/PCNs/Texas%20Instruments/PCN20120223003A_Copper-wire.pdf",

"PCN Design/Specification", "", "", "Material Set 30/Mar/2017", "http://media.digikey.com/pdf/PCNs/Texas%20Instruments/PCN20170310000.pdf",

In the table I've created in SQL it uses the same column names as the keys in the JSON array. 在我用SQL创建的表中,它使用与JSON数组中的键相同的列名。 There are several arrays in the JSON response so I'm hoping to create a generic function that accepts the JSON array and creates the correct SQL INSERT statements to populate the tables with the JSON data. JSON响应中有多个数组,因此我希望创建一个通用函数,该函数接受JSON数组并创建正确的SQL INSERT语句以用JSON数据填充表。 I'm planning on using pyodbc and best case is something that works for both Python 2.7 as well as 3.x 我正在计划使用pyodbc,最好的情况是它对Python 2.7和3.x都适用

Updated Information: 更新信息:

I found the following code snippet which comes very close: 我发现以下代码片段非常接近:

for thedata in data['PartDetails']['MediaLinks']:
    keys, values = zip(*thedata.items())
    print(values) #This will create the VALUES for the INSERT Statement
print(keys) #This will create the COLUMNS, need to add the PartDetailsId field

I was trying to find a way to get the keys before I ran this for loop because I would have to replace the print statements with the actual SQL INSERT statement. 我试图在运行此for循环之前找到一种获取密钥的方法,因为我将不得不用实际的SQL INSERT语句替换print语句。

When I check type(newdata['PartDetails']['MediaLinks']) is returns <class 'list'> in Python 3.7.4 so even though it looks like a dictionary it's treated like a list and .keys() fails to try and grab the keys 当我检查type(newdata['PartDetails']['MediaLinks'])在Python 3.7.4中返回<class 'list'> type(newdata['PartDetails']['MediaLinks']) <class 'list'> ,所以即使它看起来像字典,它也像列表一样对待,而.keys()无法尝试抓住钥匙

Use cursor.executemany() to execute the query on all the rows in the MediaLinks list. 使用cursor.executemany()MediaLinks列表中的所有行执行查询。

You can't pass the dictionaries directly, though, because iterating over a dictionary returns the keys, not the values. 但是,您不能直接传递字典,因为对字典进行迭代会返回键,而不是值。 You need to convert this to a list of values, using one of the methods in How to convert list of dictionaries into list of lists 您需要使用如何将字典列表转换为列表列表中的方法之一,将其转换为值列表

colnames = ", ".join (data['PartDetails']['MediaLinks'][0].keys())
placeholders = ", ".join(["?"] * len(data['PartDetails']['MediaLinks'][0]))
query = "INSERT INTO MediaLInks (" + colnames + ") VALUES (" + placeholders + ")"
cursor.executemany(query, [tuple(d.values()) for d in data['PartDetails']['MediaLinks']])

Just for completeness I want to post a formatted code snippet that is working for me. 为了完整起见,我想发布一个对我有用的格式化代码段。 This would not have been possible without @barmar 's help so thanks again. 没有@barmar的帮助,这是不可能的,再次感谢。

The end goal is to convert this into a function so that I can pass in the arrays from a JSON response and have it populate the correct SQL tables with the data. 最终目标是将其转换为函数,以便我可以从JSON响应中传递数组,并用数据填充正确的SQL表。 This is close to being complete but not quite there yet. 这接近完成,但还不完全到此。

import pyodbc

conn = pyodbc.connect('Driver={SQL Server};Server=GEORGE-OFFICE3\SQLEXPRESS01;Database=Components;')

cursor = conn.cursor()

with open(r"C:\Users\george\OneDrive\Documents\296-1592-5-ND.json") as json_file:
    data = json.load(json_file)

x = tuple(data['PartDetails']['MediaLinks'][0])
a = str(x).replace("'","").replace("(","")

query = "INSERT INTO MediaLinks (PartDetailsId, " + a + " VALUES(" + str(data['PartDetails']['PartId'])

b = ""
for i in range(len(x)):
    b += ", ?"
b += ")"

query += b

cursor.executemany(query, [tuple(d.values()) for d in data['PartDetails']['MediaLinks']])
cursor.commit()

conn.close()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM