psycopg2操作PostgreSQL自定义ENUM数组时如何对元素做类型转换
方案1:SQL端直接强转数组(最简方案)
不需要额外定义适配器,只需要修改你的SQL语句,对插入的数组整体做类型转换即可:
foo = "my_text" sources = ["ftp", "http"] cursor.execute( """ INSERT INTO data(foo, sources) VALUES (%s, %s::data_source[]) """, (foo, sources), )
psycopg2会自动把Python列表转为PostgreSQL的ARRAY类型,后面加::data_source[]就会把整个数组转为你自定义的枚举数组类型,完全不需要修改业务代码的结构。
方案2:修复你写的适配器方案
你原来的代码有两个问题:
getquoted()返回的是bytes类型,直接拼接进字符串会保留b''标识,导致SQL语法错误- 格式化字符串末尾多写了一个多余的单引号
'
修改后的适配器代码如下:
import psycopg2 from psycopg2 import extensions class Source: def __init__(self, source): self.string = source def adapt_source(source): # 先把getquoted返回的bytes解码为字符串 quoted = extensions.adapt(source.string).getquoted().decode('utf-8') # 去掉多余的末尾单引号 return extensions.AsIs(f"{quoted}::data_source") extensions.register_adapter(Source, adapt_source) # 后续插入代码不变 foo = "my_text" sources = [Source("ftp"), Source("http")] cursor.execute( """ INSERT INTO data(foo, sources) VALUES (%s, %s) """, (foo, sources), )
这种方案适合需要多处插入该枚举类型、不想每次写SQL都加类型强转的场景。
内容的提问来源于stack exchange,提问作者Vojta Myslivec
相关产品推荐
相关产品推荐

