使用psycopg2调用postgres函数,该函数接受自定义类型的数组

时间:2018-11-20 16:03:57

标签: python-3.x postgresql psycopg2

我目前在postgres中有一个自定义类型:

create type times_type as
(
  start varchar,
  end   varchar,
  rate real
);

我还有一个函数,它接受一个times_type数组:

create function insert_data(times_values times_type[])

当我使用命名元组并使用callproc一次插入一个值时,它工作正常,即:

 Document = namedtuple('times_type', 'start 
                             end rate')


 cur.callproc('insert_data',
                     (Document('13:00', '16:00', 12.56))

但是现在函数需要一个数组,所以我尝试了:

Document = namedtuple('times_type', 'start 
                             end rate')


 cur.callproc('insert_data',
                     ([Document('13:00', '16:00', 12.56),
                       Document('17:00', '18:00', 12.56),
                       Document('19:00', '20:00', 12.56)])

psycopg2给我一个错误,提示该函数不存在。处理自定义类型数组时,您需要做些什么吗?

1 个答案:

答案 0 :(得分:0)

复合类型数组的问题在于必须显式地转换它们,否则Postgres会将它们视为record[]。使用register_adapter(class, adapter)

Document = namedtuple('times_type', 'start end rate')

class DocumentAdapter:
    def __init__(self, x):
        self.adapted = psycopg2.extensions.SQL_IN(x)
    def prepare(self, conn):
        self.adapted.prepare(conn)
    def getquoted(self):
        return self.adapted.getquoted() + b'::times_type'

psycopg2.extensions.register_adapter(Document, DocumentAdapter)

cur.callproc('insert_data',
                     ([Document('13:00', '16:00', 12.56),
                       Document('17:00', '18:00', 12.56),
                       Document('19:00', '20:00', 12.56)],)) # comma added, this should be a tuple

conn.commit();  # dont forget to commit