简体   繁体   English

Python pickle丢失数据

[英]Python pickle loses data

I have 4 nested classes, see example: 我有4个嵌套的类,请参见示例:

class GameInfo:
    id = ""
    round = ""
    # ... etc

class Opponent:
    game_info = GameInfo()
    name = ""
    # ...

class Tournament:
    opponent_list = [] # list of Opponent objects
    # ...

class Journal(db.Model):
    picked_tournament = db.BlobProperty()  # here I put picked Tournament object

the problem is: when I unpickle pickled_tournament in Journal all data from GameInfo is lost. 问题是:当我在Journal pickled_tournament时, GameInfo所有数据都丢失了。 Ie opponent.name shows correct value, but opponent.game_info.id shows empty string. 也就是说, opponent.name显示正确的值,而opponent.game_info.id显示空字符串。

I use Google App Engine datastore to store data and picked_tournament is stored in BlobProperty(). 我使用Google App Engine数据存储区来存储数据,而picked_tournament存储在BlobProperty()中。 To serialize data I invoke: journal.picked_tournament = pickle.dumps(tournament) . 要序列化数据,我调用: journal.picked_tournament = pickle.dumps(tournament) To load data I use: tournament = pickle.loads(journal.picked_tournament) 要加载数据,我使用: tournament = pickle.loads(journal.picked_tournament)

Why pickle is not going deeper than 2 levels? 为什么泡菜的深度不超过2个水平?

UPD: data is set as follows: UPD:数据设置如下:

gi = GameInfo()
gi.id = "1234"
opp = Opponent()
opp.name = "John"
opp.game_info = gi
t = Tournament()
t.opponent_list.append(opp)
# etc...

UPD2: just discovered that everything works fine on development server if database is sqlite3, but does not work without sqlite3 and on appspot! UPD2:刚发现,如果数据库是sqlite3,则在开发服务器上一切正常,但是如果没有sqlite3和appspot,则一切正常!

In the constructor for your Opponent class, you instantiate a single copy of GameInfo , which is used by all the instances of that class. Opponent类的构造函数中,实例化GameInfo的单个副本,该类的所有实例都使用该副本。 For example: 例如:

>>> o1 = Opponent()
>>> o1.game_info.id = 5
>>> o2 = Opponent()
>>> o2.game_info.id
5

Instead, you need to create one for each Opponent instance. 相反,您需要为每个Opponent实例创建一个。 Do this by initializing it in the constructor, like this: 通过在构造函数中对其进行初始化,如下所示:

class Opponent:
    def __init__(self):
        game_info = GameInfo()

Also, since it's not the 1990s, you really should be using new style classes . 另外,由于不是1990年代,因此您确实应该使用新样式类

Based on App Engine documentation (I haven't tried it in practice), try setting the pickle data as a blob: 根据App Engine文档(我尚未在实践中尝试过),尝试将泡菜数据设置为Blob:

journal.picked_tournament = db.Blob(pickle.dumps(tournament))

If this doesn't work, verify that journal.picked_tournament == pickle.dumps(tournament). 如果这不起作用,请验证journal.picked_tournament == pickle.dumps(tournament)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM