0

I'm getting this error KeyError: 'country.id' when I use psycopg2 to insert a list with a nested dictionary into a table in postgres:

import psycopg2
import logging
from psycopg2.extras import LoggingConnection
def insert_fixture_data(match: dict):
    conn = psycopg2.connect(
        connection_factory=LoggingConnection, **db_settings)

    home_team = match['home_team']
    home_manager = home_team['managers']


    sql_updates = (
        "INSERT INTO manager (id,country_id,name,nickname,birth_date) VALUES (%(id)s,%(country.id)s,%(name)s,%(nickname)s,%(dob)s) ON CONFLICT DO NOTHING RETURNING id;"
    )

    try:
        cursor = conn.cursor()

        cursor.executemany(sql_updates, 
            home_manager)

    except Exception as error:
        print(error)
    finally:
        conn.close()

home_manager looks like this:

[{'id': 665, 'name': 'Ivan Juric', 'nickname': None, 'dob': '1975-08-25', 'country': {'id': 56, 'name': 'Croatia'}}]

The schema and column names were correct when I checked in postgresql.

1
  • 2
    The error is on this country.id not country_id. You are assuming country.id is going to select 'country': {'id': ... and that is not the case. Commented Jan 4, 2023 at 1:01

1 Answer 1

1

One possible solution.

Setup table

create table manager(id integer, country_id integer, name varchar,nickname varchar, birth_date date);

Python code:

import psycopg2
con = psycopg2.connect("dbname=test user=postgres host=localhost port=5432")
sql_updates = (
        """INSERT INTO manager
    (id,country_id,name,nickname,birth_date) 
    VALUES (%(id)s,(country_id)s,%(name)s,%(nickname)s,%(dob)s) 
     ON CONFLICT DO NOTHING RETURNING id"""
    )

home_manager = [{'id': 665, 'name': 'Ivan Juric', 'nickname': None, 'dob': '1975-08-25', 'country': {'id': 56, 'name': 'Croatia'}}]
# Pull out nested dict. pop() removes the dict and key associated with
# the  'country' key.
country = home_manager[0].pop('country')
# Add back the country id as item with key 'country_id' and value 
# 'id' to the dict in home_manager.
home_manager[0].update({'country_id': country['id']})

cur = con.cursor()
cur.executemany(sql_updates, home_manager)
con.commit()

cur.execute("select * from manager")

cur.fetchone()
(665, 56, 'Ivan Juric', None, datetime.date(1975, 8, 25))


Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.