Có vẻ như bạn muốn tạo một bảng có một cột có tên là "data"
. Loại của cột này là JSON. (Tôi khuyên bạn nên tạo một cột cho mỗi trường, nhưng điều đó tùy thuộc vào bạn.)
Trong trường hợp này, biến data
(được đọc từ yêu cầu) là một list
trong tổng số dict
S. Như tôi đã đề cập trong nhận xét của mình, bạn có thể lặp lại data
và thực hiện chèn lần lượt dưới dạng executemany()
không nhanh hơn nhiều lệnh gọi đến execute()
.
Những gì tôi đã làm như sau:
- Tạo danh sách các trường mà bạn quan tâm.
- Lặp lại các phần tử của
data
- Đối với mỗi
item
trong dữ liệudata
, trích xuất các trường thànhmy_data
- Gọi
execute()
và chuyển vàojson.dumps(my_data)
(Chuyển đổimy_data
từ mộtdict
thành một chuỗi JSON)
Hãy thử điều này:
#!/usr/bin/env python
import requests
import psycopg2
import json
conn = psycopg2.connect(database='NHL', user='postgres', password='postgres', host='localhost', port='5432')
req = requests.get('http://www.nhl.com/stats/rest/skaters?isAggregate=false&reportType=basic&isGame=false&reportName=skatersummary&sort=[{%22property%22:%22playerName%22,%22direction%22:%22ASC%22},{%22property%22:%22goals%22,%22direction%22:%22DESC%22},{%22property%22:%22assists%22,%22direction%22:%22DESC%22}]&cayenneExp=gameTypeId=2%20and%20seasonId%3E=20172018%20and%20seasonId%3C=20172018')
# data here is a list of dicts
data = req.json()['data']
cur = conn.cursor()
# create a table with one column of type JSON
cur.execute("CREATE TABLE t_skaters (data json);")
fields = [
'seasonId',
'playerName',
'playerFirstName',
'playerLastName',
'playerId',
'playerHeight',
'playerPositionCode',
'playerShootsCatches',
'playerBirthCity',
'playerBirthCountry',
'playerBirthStateProvince',
'playerBirthDate',
'playerDraftYear',
'playerDraftRoundNo',
'playerDraftOverallPickNo'
]
for item in data:
my_data = {field: item[field] for field in fields}
cur.execute("INSERT INTO t_skaters VALUES (%s)", (json.dumps(my_data),))
# commit changes
conn.commit()
# Close the connection
conn.close()
Tôi không chắc chắn 100% liệu tất cả cú pháp postgres ở đây có đúng không (tôi không có quyền truy cập vào cơ sở dữ liệu PG để kiểm tra), nhưng tôi tin rằng logic này sẽ hoạt động cho những gì bạn đang cố gắng thực hiện.
Cập nhật cho các cột riêng biệt
Bạn có thể sửa đổi câu lệnh tạo của mình để xử lý nhiều cột, nhưng nó sẽ yêu cầu biết kiểu dữ liệu của mỗi cột. Đây là một số mã psuedoc bạn có thể làm theo:
# same boilerplate code from above
cur = conn.cursor()
# create a table with one column per field
cur.execute(
"""CREATE TABLE t_skaters (seasonId INTEGER, playerName VARCHAR, ...);"""
)
fields = [
'seasonId',
'playerName',
'playerFirstName',
'playerLastName',
'playerId',
'playerHeight',
'playerPositionCode',
'playerShootsCatches',
'playerBirthCity',
'playerBirthCountry',
'playerBirthStateProvince',
'playerBirthDate',
'playerDraftYear',
'playerDraftRoundNo',
'playerDraftOverallPickNo'
]
for item in data:
my_data = [item[field] for field in fields]
# need a placeholder (%s) for each variable
# refer to postgres docs on INSERT statement on how to specify order
cur.execute("INSERT INTO t_skaters VALUES (%s, %s, ...)", tuple(my_data))
# commit changes
conn.commit()
# Close the connection
conn.close()
Thay thế ...
với các giá trị thích hợp cho dữ liệu của bạn.