GAE: ValueError: 不安全的字符串拾取

3 投票
2 回答
4154 浏览
提问于 2025-04-15 23:29

我在从Google App Engine中解压缩对象时遇到了麻烦。我使用的是Windows 7。以下是我的操作步骤:

  1. 创建一个CSV文件,其中一个字段是 pickle.dumps([[('CS', 2110), ('CS', 3300), ('CS', 3140)]]),或者类似的内容。

这个CSV文件看起来像这样:

INFO,2210,"CS 2110, 3300, 3140","(lp0
(lp1
(S'CS'
p2
I2110
tp3
a(g2
I3300
tp4
a(g2
I3140
tp5
aa."

CS,3110,CS 2110 or equivalent experience,"(lp0
(lp1
(S'CS'
p2
I2110
tp3
aa."

MSE,4102,"MATH 2210, 2230, 2310, or 2940","(lp0
(lp1
(S'MATH'
p2
I2210
tp3
a(g2
I2230
tp4
a(g2
I2310
tp5
aa(lp6
(g2
I2940
tp7
aa."

(没错,这些是 pickle.dumps() 生成的 \n)

  1. 将这个文件加载到Google App Engine的开发服务器中:

appcfg.py upload_data --config_file="DataLoader.py" --filename="pre_req_data.csv" --kind=Course --url=http://localhost:8083/remote_api "appdir"

课程模型:

class Course(db.Model):
    dept_code = db.StringProperty()
    number = db.IntegerProperty()
    raw_pre_reqs = db.StringProperty(multiline=True)
    original_description = db.StringProperty()

    def getPreReqs(self):
        pickle.loads(str(self.raw_pre_reqs))

DataLoader.py:

class CourseLoader(bulkloader.Loader):
    def __init__(self):
        bulkloader.Loader.__init__(self, 'Course',
                                   [('dept_code', str),
                                    ('number', int),
                                    ('original_description', str),
                                    ('raw_pre_reqs', str)
                                   ])

loaders = [CourseLoader]
  1. 确认数据是否成功加载:

数据存储单个实体

  1. 尝试解压缩:

    class MainHandler(webapp.RequestHandler):

    def get(self):
        self.writeOut('cock!')
        self.writeOut('\n')
    
        courses = Course().all()
        for c in courses:
            self.writeOut("%s => %s" % (c.raw_pre_reqs, c.getPreReqs()))
    
    def writeOut(self, string):
        self.response.out.write(string)
    
  2. 观察到错误:

    追踪信息(最近的调用在最前面):

    文件 "C:\Program Files\Google\google_appengine\google\appengine\ext\webapp__init__.py",第511行,在 call handler.get(*groups)

    文件 "main.py",第30行,在 get self.writeOut("%s => %s" % (c.raw_pre_reqs, c.getPreReqs()))

    文件 "src\Models.py",第17行,在 getPreReqs pickle.loads(str(self.raw_pre_reqs))

    文件 "C:\Python26\lib\pickle.py",第1374行,在 loads return Unpickler(file).load()

    文件 "C:\Python26\lib\pickle.py",第858行,在 load dispatchkey

    文件 "C:\Python26\lib\pickle.py",第966行,在 load_string raise ValueError, "不安全的字符串解压缩"

    ValueError: 不安全的字符串解压缩

我在这里做错了什么?

2 个回答

2

Pickle可以是一种二进制格式,但默认情况下它是完全安全的ASCII格式(协议0)。想了解更多细节,可以查看Pickle的文档:pickle.dump

通常情况下,它会有换行符,所以在使用像CSV这样的基于行的格式时,你需要考虑到这一点。

如果你在读取别人的Pickle文件,他们可能使用了二进制协议,但你粘贴的输出看起来像是正常的Pickle格式。

4

Pickle是一种二进制格式,而CSV格式则不适合存储二进制数据。如果你想在文本格式中传输Pickle数据,就需要对它进行编码,比如使用base64.b64encode这个方法。

撰写回答