开发者

Python pickle loses data

I have 4 nested classes, see example:

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. I.e. opponent.name shows correct value, but opponent.game_info.id shows empty string.

I use Google App Engine datastore to store data and picked_tournament is stored in BlobProperty(). To serialize data I invoke: journal.picked_tournament = pickle.dumps(tournament). To load data I use: tournament = pickle.loads(journal.picked_tournament)

Why pickle is not going deeper than 2 levels?

UPD: data is set as follows:

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 f开发者_开发技巧ine on development server if database is sqlite3, but does not work without sqlite3 and on 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. 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. 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.


Based on App Engine documentation (I haven't tried it in practice), try setting the pickle data as a blob:

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

If this doesn't work, verify that journal.picked_tournament == pickle.dumps(tournament).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜