4

我正在开发一个在 Google 的 AppEngine 上运行的 django-nonrel 项目。我想为游戏创建一个模型,其中包含所有运动通常共有的细节——即比赛时间、状态、位置等。然后我为 GameBasketball、GameBaseball 等建模了特定的类,这些类继承自基类。

但是,如果我想在某一天检索所有游戏之类的东西,这会产生一个问题:

Game.objects.filter(gametime=mydate)

这将返回一个错误:

DatabaseError: Multi-table inheritance is not supported by non-relational DBs.

我知道 AppEngine 不支持 JOIN,因此失败是有道理的。但我不确定如何在非关系环境中正确解决这个问题。我尝试过的一个解决方案是将 Game 转换为抽象基类,虽然这允许我以一种很好的方式对数据进行建模 - 它仍然无法解决上述用例,因为它无法获取抽象对象基类。

这里唯一的解决方案是将所有可能的运动的所有数据(并且只将与特定运动无关的字段保留为空)放在游戏模型中,还是有更优雅的方法来解决这个问题?

编辑:我更感兴趣的是了解在任何 noSQL 设置中处理此类问题的正确方法,而不是专门在 AppEngine 上。因此,即使您的答案不是 GAE 特定的,也请随时回复!

4

2 回答 2

1

对于将来遇到此问题的其他任何人,这就是我最终解决该问题的方法。请记住,这在某种程度上是特定于 mongo 的解决方案,并且 AFAIK 仅使用基本 nonrel 类没有简单的方法来解决这个问题。

对于 Mongo,我可以通过使用 Embedded Documents(其他 noSQL 设置可能具有类似的软模式类型功能)来解决这个问题,简化代码如下:

class Game(models.Model):
    gametime = models.DateTimeField()
    # etc

    details = EmbeddedModelField() # This is the mongo specific bit.

class GameBasketballDetails(models.Model):
    home = models.ForeignKey(Team)
    # etc

现在,当我实例化 Game 类时,我在 details 字段中保存了一个 GameBasketballDetails 对象。所以我现在可以这样做:

games = Game.objects.filter(gametime=mydate)
games[0].details.basketball_specific_method()

这是一个可以接受的解决方案,因为它允许我查询游戏模型,但仍然可以获得我需要的“孩子”特定信息!

于 2012-06-21T02:34:54.350 回答
0

如您所知,django-nonrel 中不允许多表继承的原因是 Django 为这些模型提供的 API 通常会使用 JOIN 查询。

但我认为你可以手动设置 Django 会用它的模型继承“糖”做的事情,而只是避免在你自己的代码中进行连接。

例如

class Game(models.Model):
    gametime = models.DateTimeField()
    # etc

class GameBasketball(models.Model):
    game = models.OneToOneField(Game)
    basketball_specific_field = models.TextField()

当您创建一个新实例GameBasketball以创建相应的Game实例时,您需要做一些额外的工作(您可以尝试自定义管理器类),但之后您至少可以做您想做的事情,例如

qs = Game.objects.filter(gametime=mydate)
qs[0].gamebasketball.basketball_specific_field

django-nonrel 和 djangoappengine 在 GitHub 上有一个新家:https ://github.com/django-nonrel/

除了 GAE 数据存储 API 本身的速度之外,我不相信 python 框架的选择会有很大的不同,或者 django-nonrel 天生就比 webapp2 慢。

于 2012-06-20T12:41:54.810 回答