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

Posted

技术标签:

【中文标题】为啥我不能从数据库中保存和检索我的向量(二进制)和特殊字符?【英文标题】:Why can't I save and retrieve my vector(binary) and special characters from the database?为什么我不能从数据库中保存和检索我的向量(二进制)和特殊字符? 【发布时间】:2021-12-14 10:20:40 【问题描述】:

我正在使用 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, '?'.
  '''

对不起我的英语。

【问题讨论】:

???? 是“MATHEMATICAL BOLD FRAKTUR CAPITAL G”,它需要 utf8mb4,而不是 utf8。或者是BINARYBLOB 的列。 【参考方案1】:

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

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

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

(source)

【讨论】:

【参考方案2】:

使用BLOB 列而不是TEXT

【讨论】:

以上是关于为啥我不能从数据库中保存和检索我的向量(二进制)和特殊字符?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的视图控制器没有检索到我的 CoreData 对象

为啥我的代码没有将每个对象都添加到向量中?

为啥 BotUserData 在我的 Bot Framework 机器人中不能持久化和可检索?

为啥我不能从文件中复制字符串并将其注册到对象中?

为啥我不能直接从向量中的函数 push_back 更新值? [关闭]

如何使用 jdatechooser 从 mysql 数据库中保存和检索空日期