为什么我不能从数据库中保存和检索我的矢量(二进制)和特殊字符?

Why can't I save and retrieve my vector(binary) and special characters from the database?

我正在使用 python 模块 'face_recognition' 和 'pickle' 和 DB 'PostgreSQL' 从数据库中保存和检索我的面部向量,但是我我遇到了编码问题。

如果未启用 UTF-8 编码,我无法将规范字符“”保存到我的数据库中。

启用 UTF-8 编码后,我无法从数据库取回我的对象​​。

import cv2
import pickle
import face_recognition
import mysql.connector as mysql        
      
conn = mysql.connect(
      host = 'localhost',
      user = 'root',
      passwd = 'superpassword'
    )
    

# Open image
img = face_recognition.load_image_file('test.jpg')
# Get vector
face_vector = face_recognition.face_encodings(img)[0]
    
    
 cur = conn.cursor(buffered=True)
 cur.execute("CREATE DATABASE IF NOT EXISTS test;")
    
 cur.execute("USE test;")
    
 # WITHOUT UTF-8 I GETTING THIS ERROR:
 # Error: mysql.connector.errors.DataError: 1366 (22007): Incorrect string value: '\xF0\x9D\x95\xB2' for column `test`.`test`.`bug_char` at row 1
 #cur.execute("SET NAMES 'utf8';")
 #cur.execute("SET CHARACTER SET utf8;")
    
 cur.execute("CREATE TABLE faces(bug_char VARCHAR(32), vectors BLOB)")
    
 data_insert = ('', pickle.dumps(face_vector))
 cur.execute('INSERT INTO faces(bug_char, vectors) VALUES(%s, %s)', data_insert)
    
 cur.execute("SELECT * FROM faces;")
 face_data = cur.fetchall()
    
    
 for f in face_data:
    print(pickle.loads(f[1]))
        
    
  # AND WITH UTF-8 I GETTING THIS ERROR WHEN I TRY TO GET MY OBJ FROM DB:
  '''
  Traceback (most recent call last):
  File "/home/user/Desktop/parser_steam/image_recognition/test/./test.py", line 203, in <module>
  print(pickle.loads(f[1]))
  _pickle.UnpicklingError: invalid load key, '?'.
  '''

对不起我的英语。

每个面部编码都是 128 个浮点数的列表...以下可能很好地解释了为什么会提出您的问题以及该怎么做。

"pickling 是递归的,而不是顺序的。因此,要 pickle 列表,pickle 将开始 pickle 包含列表,然后 pickle 第一个元素......深入到第一个元素并 pickle 依赖项和子元素直到第一个元素被序列化。然后移动到列表的下一个元素,依此类推,直到它最终完成列表并完成对封闭列表的序列化。简而言之,很难将递归 pickle 视为顺序的,除了一些特殊情况. 如果您想以特殊方式加载,最好在转储中使用更智能的模式。

最常见的 pickle,它通过一次转储将所有内容 pickle 到一个文件中——但是您必须一次加载所有内容。但是,如果您打开一个文件句柄并进行多次转储调用(例如,一个用于列表中的每个元素,或一个选定元素的元组),那么您的加载将反映……您打开文件句柄并进行多次加载调用,直到您拥有所有列表元素并可以重建列表。然而,选择性地只加载某些列表元素仍然不容易。为此,您可能必须使用像 klepto 这样的包将列表元素存储为字典(以元素或块的索引作为键),它可以透明地将腌制字典分解成几个文件,并启用轻松加载特定元素。"

使用 BLOB 列代替 TEXT