Psycopg2 автоматически преобразует кортеж в запись

#python #postgresql

Вопрос:

Учитывая следующий запрос,

 SELECT_TOP_DOWNTIMES2: str = """SELECT downtime_cause, 
                                sum(downtime_duration_seconds) total_downtime_duration_seconds
                                FROM dw.dt_causes_by_production_line2(%s, %s, %s, %s, %s, %s, %s)
                                GROUP BY downtime_cause
                                ORDER BY total_downtime_duration_seconds desc
                                LIMIT 5
                                """
 

где функция определяется как

 dt_causes_by_production_line2(
_client_id character varying,
_start_timestamp timestamp without time zone, 
_end_timestamp timestamp without time zone,
_is_planned integer, _shifts character varying[], 
_product_skus character varying[],
_production_line_names character varying[])
    returns TABLE(
         production_line_name character varying,
         downtime_cause character varying,
         is_planned integer,
         downtime_duration_seconds double precision
)
 

Я пытаюсь выполнить функцию с помощью этого вызова

 pg.select_with_params(SELECT_TOP_DOWNTIMES2, customerid, startdate, enddate, downtimeType, shifts, product_list, production_lines)]
 

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

 psycopg2.errors.UndefinedFunction: function dw.dt_causes_by_production_line2(unknown, unknown, unknown, unknown, unknown, unknown, record) does not exist
LINE 3:                                 FROM dw.dt_causes_by_product...
 

Как ни странно, я могу выполнить этот запрос непосредственно в базе данных, но у psycops, похоже, возникли некоторые проблемы. Я подозревал, что кортеж производственных линий каким-то образом преобразуется в запись, а не в массив с переменными символами. Я изменил свой запрос, чтобы привести производственные линии в виде массива с переменными символами
dt_causes_by_production_line2(%s, %s, %s, %s, %s, %s, %s::character varying)
но возвращенная ошибка такова

psycopg2.errors.CannotCoerce: cannot cast type record to character varying[]

Есть ли способ настроить psycopgs2, чтобы остановить преобразование кортежа в запись?

Комментарии:

1. Похоже, что получение записи было бы ожидаемым поведением. Вероятно, вам нужно покопаться в записи, чтобы получить доступ к вашим данным.

2. Я бы так подумал, но у меня есть другая функция, которая принимает массив, изменяющий символы, где я передаю кортеж, и psycops не жалуется на это.

Ответ №1:

Прочитайте этот раздел psycopg2 адаптации документов.

Краткая версия:

  1. «Списки Python преобразуются в массивы PostgreSQL:»
  2. «Кортежи Python преобразуются в синтаксис, подходящий для оператора SQL IN и представляющий составной тип».

Составьте production_lines список. Я предполагаю, что дело, которое работает, на самом деле также является списком.