导入错误:没有名为 copy_reg pickle 的模块

发布于 2024-07-13 22:34:44 字数 620 浏览 6 评论 0原文

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

ImportError: No module named copy_reg

关于为什么会发生这种情况有什么想法吗?

重现方法

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

1) 在 Windows PC 上:

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)

I'm trying to unpickle an object stored as a blob in a MySQL database. I've manually generated and stored the pickled object in the database, but when I try to unpickle the object, I get the following rather cryptic exception:

ImportError: No module named copy_reg

Any ideas as to why this happens?

Method of Reproduction

Note: Must do step 1 on a Windows PC and steps 3 and 4 on a Linux PC.

1) On a Windows PC:

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

2) Manually insert contents of text.txt into blob field of MySQL database running on linux

3) In Python running on a linux machine, fetch the contents of column from MySQL

4) Assuming that you put the contents of the blob column into a variable called data, try this:

cPickle.loads(rawString)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

装纯掩盖桑 2024-07-20 22:34:44

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

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

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

基于相关原始示例的正确代码:

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

It seems this might be caused by my method of exporting the pickled object.

This bug report seens to suggest that my issue can be resolved by exporting to a file writen in binary mode. I'm going to give this a go now and see if this solves my issue.

UPDATE: This works. The solution is to make sure you export your pickled object to a file open in binary mode, even if you are using the default protocol 0 (commonly referred to as being "text")

Correct code based on orignal example in question:

file = open("test.txt", 'wb')
thing = {'a': 1, 'b':2}
cPickle.dump(thing, file)
面如桃花 2024-07-20 22:34:44

另外,简单地在(windows创建的)pickle文件上运行dos2unix(在linux下)就解决了我的问题。 (还没有尝试过开放模式“wb”。)

Also, simply running dos2unix (under linux) over the (windows-created) pickle file solved the problem for me. (Haven't tried the open mode 'wb' thing.)
Dan

已下线请稍等 2024-07-20 22:34:44

只是一个交互式 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

just an interactive python session to show that you don't need any particular code to have this problem:

do something like this on a windows machine

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'))
>>> 

and then try to retrieve the data from a linux box

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
>>> 

the error message can be even more confusing if you are just pickling base types. this is what I get with the list [12, 1.2, '']:

ValueError: insecure string pickle
暮色兮凉城 2024-07-20 22:34:44

正如另一个答案中提到的,使用

dos2unix originalPickle.file outputPickle.file

或使用如下所示的 tr 命令(删除回车符和 ctrl-z)

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

或使用 awkgawknawk 如果是旧版本)

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

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

As mentioned in the other answer use

dos2unix originalPickle.file outputPickle.file

OR use the tr command like below (removes carriage returns and ctrl-z)

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

OR use awk (gawk or nawk if its old versions)

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

OR if you can recreate a pickle file in linux, use that.

往日 2024-07-20 22:34:44

这里发生的另一件事是,在将 pickle 转储到文件后,您似乎没有关闭该文件。 此处报告的错误有时可能是由于未关闭文件引起的(无论是在 Windows 计算机上还是其他计算机上)。

Another thing going on here is that you don't seem to have closed the file after dumping the pickle to it. the error reported here can sometimes be caused (whether on a windows machine or otherwise) by not closing the file.

南冥有猫 2024-07-20 22:34:44

我的问题:

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

当我从Windows获取model.pkl时,在我的Mac上运行此代码,这个问题即将

解决:

dos2unix model.pkl 

没问题!

my issue:

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

when i get the model.pkl from windows run this code in my mac,this issue is comming

solve:

dos2unix model.pkl 

is ok!

二智少女 2024-07-20 22:34:44

发生这种情况是因为在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”。

This happen because in Windows, new line symbol is stored as "\r\n", and that in Linux is "\n",so what you should do is to read the pickle file line by line, replace "\r\n" with "\n", and write it back to the file.

Unlike the dos2unix approach will skip binary file, this also works well for binary pickle file.

Code is simple:

#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

Also, you can use normal write mode, just change "wb" to "w" and "rb" to "e".

蓝戈者 2024-07-20 22:34:44

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

我通过将 .gitattributes 文件添加到我的存储库中解决了该问题:

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

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

I ran into this problem, because of git changing the
line endings on windows.

I solved the problem by adding a .gitattributes file to my repo:

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

See also https://github.com/actions/checkout/issues/135

悲念泪 2024-07-20 22:34:44

pickle 加载可能不会在与 python 脚本相同的位置查找。 有时目录会根据您的应用程序而变化。 在加载 pickle 之前,打印 os.getcwd() 以找出解决方案。

The pickle load may not be looking in the same location as your python script. Sometimes the directory changes on the basis of your application. Just before you load the pickle, print a os.getcwd() to work out a solution.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文