Можно ли с помощью библиотеки psycopg2 делать insert запросы с различных количеством переменных?

Подскажите, пожалуйста, возможно ли с помощью библиотеки psycopg2 делать insert запросы с различных количеством переменных
В моем случае нужно при разных сценариях иногда вставлять только user_id в таблицу в БД, а когда-то вставлять и user_id, и prod_name, и prod_article

Я могу сделать много разных функций, которые вставляют те данные, которые мне нужны, например:

def insert_prod_info_n_p(self, user_id, domain_id, prod_name, prod_price):
        """Вставляем информацию о названии и цене"""
        cur = self.con.cursor()
        cur.execute(f"INSERT INTO prod_info (user_id, domain_id, prod_name, prod_price) values ({user_id}, {domain_id}, {prod_name}, {prod_price}")
        cur.commit()

Но я бы хотел иметь одну функцию, которая бы могла передавать БД столько переменных для insert запроса, сколько я хочу
Это возможно?


Ответы (1 шт):

Автор решения: alex

возможно)

def insert_prod_info_n_p(self, **kwargs):
        """Вставляем информацию о названии и цене"""
        cur = self.con.cursor()
        keys = ','.join(kwargs.keys())
        values = ','.join((repr(x) for x in kwargs.values()))
        cur.execute(f"INSERT INTO prod_info ({keys}) values ({values})")
        cur.commit()

Это самый простой вариант. Сложнее будет если мы захотим контролировать набор параметров в соответствии с таблицей, чтобы нам не могли передать ключи не соответствующие именам столбцов. Вы сами можете получить имена и типы столбцов таблицы. И использовать эту информацию при парсинге параметров. Вариант чуть хуже, это все таки жестко прописать имена и типы столбцов в сигнатуре метода.

Что-то типо вот этого

def f(*, user_id: int, username: str, score: int = None):
    scheme = {
        "user_id": int,
        "username": str,
        "sore": int
    }

    kwargs = {}

    for column, type_ in scheme.items():
        value = locals().get(column)
        if value:
            if isinstance(value, type_):
                kwargs[column] = value
            else:
                raise TypeError(f"column {column} must be {type_}, not {type(value)}")
        else:
            continue

    keys = ','.join(kwargs.keys())
    values = ','.join((repr(x) for x in kwargs.values()))
    print(f"{keys} | {values}")

f(user_id=1, username="2")

P.S. аннотация типов поможет потом, когда IDE будет сама подсказывать еще на стадии написания кода, что тип указан не верно.

→ Ссылка