如何处理psycopg2查询ByteA[]返回的<memory>对象以获取字节数据?
解决psycopg2查询ByteA[]返回memoryview而非原始bytes的问题
问题原因
psycopg2从2.5版本开始,默认将PostgreSQL的bytea类型映射为memoryview对象,目的是减少内存复制、提升性能——memoryview是原始二进制数据的视图,而非直接复制的bytes对象。
解决方案
有两种简单可行的处理方式:
方式1:手动转换memoryview为bytes(最直接)
遍历查询结果中的每个memoryview对象,用bytes()函数直接转换为原始bytes数据:
entries = psycopg2.connect("postgres://private🤫") with entries: with entries.cursor() as cu: cu.execute("SELECT * FROM test") rows = cu.fetchall() # 处理每行的ByteA[]数组 for row in rows: # row[0]是存储的photos数组,元素为memoryview photo_bytes_list = [bytes(photo) for photo in row[0]] # 现在photo_bytes_list中就是存入时的原始bytes数据 print(photo_bytes_list) # 用于网页展示的示例(转base64 Data URI) import base64 for img_bytes in photo_bytes_list: base64_str = base64.b64encode(img_bytes).decode('utf-8') img_html = f'<img src="data:image/png;base64,{base64_str}" />' # 将img_html嵌入网页即可展示图片
方式2:全局修改psycopg2类型映射,让bytea直接返回bytes
在数据库连接初始化后,注册自定义类型转换器,让psycopg2查询bytea类型时直接返回bytes:
import psycopg2 import psycopg2.extensions # 连接数据库 entries = psycopg2.connect("postgres://private🤫") # 注册类型转换器,将bytea映射为bytes psycopg2.extensions.register_type(psycopg2.extensions.BYTEA, entries) # 后续查询将直接返回bytes数组 with entries: with entries.cursor() as cu: cu.execute("SELECT * FROM test") rows = cu.fetchall() # row[0]现在是bytes对象组成的数组 print(rows[0][0]) # 输出: [b'\x89PNG...', b'\x89PNG...']
注意事项
memoryview转bytes是轻量操作,仅在需要时复制数据,不会造成显著性能损耗。- 若用于网页展示,需将bytes转换为base64编码的Data URI(如上述示例),这是浏览器能识别的图片格式。
内容的提问来源于stack exchange,提问作者sad programmer
相关产品推荐
相关产品推荐

