22

我正在尝试取消在 MySQL 数据库中存储为 blob 的对象。我已经手动生成了腌制对象并将其存储在数据库中,但是当我尝试取消腌制对象时,我得到以下相当神秘的异常:

ImportError:没有名为 copy_reg 的模块

关于为什么会发生这种情况的任何想法?

繁殖方法

注意:必须在 Windows PC 上执行步骤 1,在 Linux PC 上执行步骤 3 和 4。

1) 在 Windows 电脑上:

file = open("test.txt", "w")
thing = {'a': 1, 'b':2}
cPickle.dump(thing, file)

2) 手动将 text.txt 的内容插入到运行在 linux 上的 MySQL 数据库的 blob 字段中

3)在Linux机器上运行的Python中,从MySQL获取列的内容

4)假设您将 blob 列的内容放入一个名为 data 的变量中,试试这个:

cPickle.loads(rawString)
4

9 回答 9

24

看来这可能是由我导出腌制对象的方法引起的。

这个错误报告表明我的问题可以通过导出到以二进制模式写入的文件来解决。我现在要试一试,看看这是否能解决我的问题。

更新:这有效。解决方案是确保将腌制对象导出到以二进制模式打开的文件中,即使您使用的是默认协议 0(通常称为“文本”)

基于有问题的原始示例的正确代码:

file = open("test.txt", 'wb')
thing = {'a': 1, 'b':2}
cPickle.dump(thing, file)
于 2009-02-17T10:52:36.110 回答
16

此外,只需在(windows-created)pickle 文件上运行 dos2unix(在 linux 下)为我解决了这个问题。(还没有尝试过打开模式“wb”的东西。)丹

于 2009-04-17T13:50:01.900 回答
3

只是一个交互式 python 会话来表明你不需要任何特定的代码来解决这个问题:

在 Windows 机器上做这样的事情

Python 2.4.1 (#65, Mar 30 2005, 09:13:57) [MSC v.1310 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import pickle, re
>>> empty_string = re.compile("^$")
>>> pickle.dump([empty_string,1,1.23,'abc'], file('m:/mario/test-b.dump','wb'))
>>> pickle.dump([empty_string,1,1.23,'abc'], file('m:/mario/test-t.dump','wt'))
>>> 

然后尝试从 linux 机器中检索数据

Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41) 
[GCC 4.3.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import pickle
>>> pickle.load(file('/home/mario/.gvfs/transfer on 192.168.0.4/mario/test-b.dump'))
/usr/lib/python2.6/pickle.py:1124: DeprecationWarning: The sre module is deprecated, please import re.
  __import__(module)
[<_sre.SRE_Pattern object at 0xb7d42420>, 1, 1.23, 'abc']
>>> pickle.load(file('/home/mario/.gvfs/transfer on 192.168.0.4/mario/test-t.dump'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.6/pickle.py", line 1370, in load
    return Unpickler(file).load()
  File "/usr/lib/python2.6/pickle.py", line 858, in load
    dispatch[key](self)
  File "/usr/lib/python2.6/pickle.py", line 1090, in load_global
    klass = self.find_class(module, name)
  File "/usr/lib/python2.6/pickle.py", line 1124, in find_class
    __import__(module)
ImportError: No module named sre
>>> 

如果您只是腌制基本类型,则错误消息可能会更加令人困惑。这是我从列表中得到的[12, 1.2, '']

ValueError: insecure string pickle
于 2009-08-07T14:42:46.120 回答
2

如另一个答案中所述,使用

dos2unix originalPickle.file outputPickle.file

或者使用下面的 tr 命令(删除回车和 ctrl-z)

  tr -d '\15\32' < originalPickle.file > outputPickle.file

或者使用awkgawk或者nawk如果它的旧版本)

  awk '{ sub("\r$", ""); print }' originalPickle.file > outputPickle.file

或者,如果您可以在 linux 中重新创建一个 pickle 文件,请使用它。

于 2015-10-30T10:47:23.590 回答
1

这里发生的另一件事是,在将泡菜倾倒到文件后,您似乎没有关闭文件。此处报告的错误有时可能是由不关闭文件引起的(无论是在 Windows 机器上还是在其他情况下)。

于 2014-10-19T02:09:30.913 回答
1

我的问题:</p>

with open('model.pkl', 'rb') as f:
    subsection_struct_model = pickle.load(f)

当我从 Windows 获取 model.pkl 在我的 Mac 中运行此代码时,此问题即将出现

解决:

dos2unix model.pkl 

没关系!

于 2018-08-28T02:40:28.860 回答
1

这是因为在Windows中,换行符存储为“\r\n”,而在Linux中为“\n”,所以你应该做的是逐行读取pickle文件,替换“\r\n " 与 "\n",并将其写回文件。

与 dos2unix 方法将跳过二进制文件不同,这也适用于二进制 pickle 文件。

代码很简单:

#run this code on Linux platform

DIR="your/dir/to/file"

pickle.load(open(DIR,"rb"))
# ImportError: No module named copy_reg pickle

a=open(DIR,"rb").readlines() #read pickle file line by line

a=map(lambda x:x.replace("\r\n","\n"),a) # replace \r\n with \n

with open(DIR,"wb") as j: #write back to file in binary mode
    for i in a:
        j.write(i)         
pickle.load(open(DIR,"rb")) 
#Now it works well

此外,您可以使用普通写入模式,只需将“wb”更改为“w”,将“rb”更改为“e”。

于 2018-12-27T09:01:40.610 回答
1

我遇到了这个问题,因为 git 改变了 windows 上的行尾。

.gitattributes我通过向我的仓库添加一个文件解决了这个问题:

# Pickle files (for testing) should always have UNIX line endings. 
*.pkl text eol=lf

另请参阅https://github.com/actions/checkout/issues/135

于 2020-05-25T09:24:53.193 回答
0

泡菜负载可能与您的 python 脚本不在同一位置。有时目录会根据您的应用程序而更改。就在你加载泡菜之前,打印一个 os.getcwd() 来制定一个解决方案。

于 2016-02-16T17:55:58.687 回答