Я пытаюсь разработать и реализовать модель базы данных в python из файла json, но мой код python, похоже, не вставляет данные в таблицу, и я не уверен, в чем проблема в моем коде
import json
import psycopg2
class Policy:
def __init__(self, type, name, rule_exists):
self.type = type
self.name = name
self.rule_exists = rule_exists
# load json data from the file
with open("demo_data.json", 'r') as file:
policy_data = json.load(file)
first_level = policy_data["uniconfig-topology:configuration"]
second_level = first_level["Cisco-IOS-XR-infra-policymgr-cfg:policy-manager"]
third_level = second_level["policy-maps"]
forth_level = third_level["policy-map"]
table_of_policies = []
for item in forth_level:
if "policy-map" in item:
# forth_level = item
type = forth_level['type']
name = forth_level['name']
rule_exists = 'policy-map-rule' in forth_level
policy_map = Policy(type, name, rule_exists)
table_of_policies.append(policy_map)
#print(forth_level)
conn = psycopg2.connect(
host = "localhost",
database = "postgres",
user = "postgres",
password = "postgres",
port = "5432"
)
cursor = conn.cursor()
cursor.execute("DROP TABLE IF EXISTS policy_map")
cursor.execute('''create table policy_map
( type VARCHAR(255),
name VARCHAR(255),
rule_exists BOOLEAN)
''')
for policy_map in table_of_policies:
insert_data = "INSERT INTO policy_map (type, name, rule_exists) VALUES (%s, %s, %s)"
cursor.execute(insert_data, (policy_map.type,
policy_map.name, policy_map.rule_exists))
conn.commit()
Я пробовал несколько разных подходов к dict в файле json, чтобы быть уверенным, что я на правильном уровне dict, но он никогда не добавлял никаких данных в мой список. Хотел бы знать, что не так с моим кодом
Так проблема в том, что table_of_policies всегда остаются пустыми? Это когда-нибудь возвращает true? "policy-map" in item
Не могли бы вы объяснить мне, что вы подразумеваете под точным уровнем dict в json? Вы имеете в виду печатные элементы: "тип" "имя" "политика-карта-правило" ... вот так?
печатные элементы - это все строки кода под dict "policy-map"






type — это встроенная функция Python, которая возвращает тип переменной. Перезапись может привести к неожиданной работе вашего кода.
Вы можете проверить документацию, избегайте использования имен встроенных функций для переменных.
Что касается именования столбцов таблицы, вы можете обратиться к этому вопросу.
Помимо этого, вы зацикливаетесь на forth_level, но не используете элемент:
type = forth_level['type']
name = forth_level['name']
Я ожидаю, что этот код будет продолжаться так:
if "policy-map" in item:
type = item['type']
name = item['name']
rule_exists = 'policy-map-rule' in item
policy_map = Policy(type, name, rule_exists)
table_of_policies.append(policy_map)
Но не видя JSON, я не могу сказать наверняка.
Это не проблема, даже если я заменю переменную с именем типа, она все равно не добавит никаких данных.
Я добавил еще одну возможную проблему с вашим кодом, но не видя фактического файла, который вы используете, это просто интуиция, поскольку предыдущая версия в конечном итоге возвращала дубликаты.
Считайте содержимое файла demo_data.json в строковую переменную, т. е. json_text = file.read(), а затем передайте json_text в качестве одного параметра этому запросу (в переменной the_insert_query):
with t as
(
select j ->> 'name' as "name",
j ->> 'type' as "type",
j -> 'policy-map-rule' is not null as rule_exists
from json_array_elements
(
%s::json -> 'uniconfig-topology:configuration'
-> 'Cisco-IOS-XR-infra-policymgr-cfg:policy-manager'
-> 'policy-maps'
-> 'policy-map'
) as j
)
insert into policy_map("name", "type", rule_exists)
select "name", "type", rule_exists from t;
cursor.execute(the_insert_query, (json_text,))
PostgreSQL справится со всем этим быстро и легко. Никакие class Policy, table_of_policies или петля над ним вообще не нужны.
Пожалуйста, опубликуйте образец данных "demo_data.json"