@Atroshchenko-Dima
Python, postgres

Как избавиться от ошибки TypeError: argument 1 must be a string or unicode object: got tuple instead?

Не могу понять почему вылазит ошибка TypeError: argument 1 must be a string or unicode object: got tuple instead.
Пробовал обработать переменную selected_years через ','.join.. но ошибка не проходит.

Функции подключения к БД и выполнения запроса
# Функция подключения к БД
def get_connection():
    conn = psycopg2.connect(**params)
    return conn

# Функция выполнения запроса
def execute_query(query, params=None):
    conn = get_connection()
    # создание объекта курсора для запуска команд PostgreSQL в базе данных
    cur = conn.cursor()
    # запрос
    cur.execute(query, params)
    # Для получения доступа к сформированной выборке используем cur.fetchall()
    rows = cur.fetchall()
    # закрытие курсора
    cur.close()
    # закрытие соединения
    conn.close()
    return rows


Обработка переменных и sql запрос
selected_years = [int(i) for i in request.form.getlist("year") if i.isdigit()]
selected_stations = [str(i) for i in request.form.getlist("station")]
selected_indicators = [str(i) for i in request.form.getlist("indicator")]
columns = columns_list + [str(i) for i in request.form.getlist("columns")]
        query = ("SELECT {} FROM fact_table WHERE year = ANY(%s) AND indicators = ANY(%s) AND station_name = ANY(%s);"
                    .format(",".join(["\"{}\"".format(c) for c in columns])),(selected_years, selected_indicators, selected_stations))
        rows = execute_query(query, (selected_years, selected_indicators, selected_stations))


Ранее мой код выглядел так, и все работало с обработкой переменных в таком виде, как это сделано сейчас (но там была проблема с idle in transaction, ну и в целом решил что лучше сделать соединение с БД отдельной функцией)
def index():
    # соединение с БД
    with psycopg2.connect(**params) as conn:
        # создание объекта курсора для запуска команд PostgreSQL в базе данных
        cur = conn.cursor()
        cur.execute("SELECT * FROM fact_table;") 
        rows = cur.fetchall()
        cur.close()
    
    if request.method == "POST":
        with psycopg2.connect(**params) as conn:
            # создание объекта курсора для запуска команд PostgreSQL в базе данных
            cur = conn.cursor()
            cur.execute("SELECT {} FROM fact_table WHERE year = ANY(%s) AND indicators = ANY(%s) AND station_name = ANY(%s);"
                        .format(",".join(["\"{}\"".format(c) for c in columns])),(selected_years, selected_indicators, selected_stations))
            # Для получения доступа к сформированной выборке используем cur.fetchall()
            rows = cur.fetchall()
            cur.close()


Подскажите, пожалуйста, в чем моя ошибка?
Данная ошибка появляется после того как на начальной странице выбраны все данные и нажата кнопка "применить"
  • Вопрос задан
  • 233 просмотра
Решения вопроса 1
sergey-gornostaev
@sergey-gornostaev Куратор тега Flask
Седой и строгий
Потому что копипаста - это зло. Вот это:
query = ("SELECT {} FROM fact_table WHERE year = ANY(%s) AND indicators = ANY(%s) AND station_name = ANY(%s);"
    .format(",".join(["\"{}\"".format(c) for c in columns])),(selected_years, selected_indicators, selected_stations))

Должно выглядеть так:
query = "SELECT {} FROM fact_table WHERE year = ANY(%s) AND indicators = ANY(%s) AND station_name = ANY(%s);"
    .format(",".join(["\"{}\"".format(c) for c in columns])

А ещё лучше убрать и это извращение с подстановкой колонок форматированием строки, оно не нужно и не безопасно.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы