Python pickle 丢失数据

发布于 2024-10-19 12:34:24 字数 1088 浏览 1 评论 0原文

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

问题是:当我在 Journal 中解绑 pickled_tournament 时,来自 GameInfo 的所有数据都会丢失。即 opponent.name 显示正确的值,但 opponent.game_info.id 显示空字符串。

我使用 Google App Engine 数据存储区来存储数据,picked_tournament 存储在 BlobProperty() 中。为了序列化数据,我调用:journal.picked_tournament = pickle.dumps(tournament)。要加载数据,我使用: tournament = pickle.loads(journal.picked_tournament)

为什么 pickle 的深度不超过 2 层?

UPD:数据设置如下:

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

UPD2:刚刚发现如果数据库是sqlite3,则在开发服务器上一切正常,但在没有sqlite3和appspot上则无法工作!

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 fine on development server if database is sqlite3, but does not work without sqlite3 and on appspot!

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

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

发布评论

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

评论(2

暗藏城府 2024-10-26 12:34:24

Opponent 类的构造函数中,您实例化 GameInfo 的单个副本,该副本由该类的所有实例使用。例如:

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

相反,您需要为每个 Opponent 实例创建一个。通过在构造函数中初始化它来完成此操作,如下所示:

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

另外,由于现在不是 20 世纪 90 年代,因此您确实应该使用 新样式类

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.

暖伴 2024-10-26 12:34:24

根据App Engine文档(我没有在实践中尝试过),尝试将pickle数据设置为blob:

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

如果这不起作用,请验证journal.picked_tournament == pickle.dumps(tournament)。

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

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