如果我有“a.py”
from google.appengine.ext import db
class A(db.Model):
db.ReferenceProperty(b.B)
...other stuff
和另一个文件“b.py”
from google.appengine.ext import db
class B(db.Model):
db.ReferenceProperty(a.A)
...other stuff
似乎Python根本不允许循环依赖。通常我猜你会改变代码,这样两个类实际上可以解决自己而不直接相互导入。也许通过第三中间人来巩固他们对彼此的引用?但我不能只使用普通的中间类,因为所有类最终都需要持久保存到数据库中?是否有任何正确的解决方案来构造上述代码,使其有效?
我有一种感觉,我会得到很多“难闻的代码”,“解耦”,“糟糕的设计”等评论。所以我想问一下,如果你这么说,请说明你用一个实际的例子做什么。有没有任何解决方案可以让参考,类和模块保持原样?
谢谢。
答案 0 :(得分:7)
解决方法是在至少一个不限制特定类的模型中使用ReferenceProperty,然后强制仅在您自己的代码中引用该类。
例如,
class A(db.Model):
b = db.ReferenceProperty()
class B(db.Model):
a = db.ReferenceProperty(A)
您可以将任何模型实例分配给b变量;只是确保你只分配实际的Bs。
答案 1 :(得分:1)
如果在同一模块中定义两个模型会发生什么?例如a_b.py
答案 2 :(得分:1)
ReferenceProperty还有另一个方便 功能:反向引用。当一个模特 有另一个ReferenceProperty 模型,每个被引用的实体得到一个 属性,其值为Query 返回的所有实体 引用它的第一个模型。
所以你应该可以使用自动添加的反向引用。
答案 3 :(得分:0)
从技术上讲,您可以使用交集表替换循环依赖项。
就我而言,我有非规范化模型,Player
和Match
。
匹配和玩家之间的关系是多对多的,(玩家玩过一次或多次比赛,匹配参考一个或多个玩家)。
我需要的是什么:
class Match(db.Model):
p1 = db.ReferenceProperty( Player )
p2 = db.ReferenceProperty( Player )
class Player(db.Model):
# Remember what match player is currently in, for victor reporting
currentMatch = db.ReferenceProperty( Match )
class Match(db.Model):
# ...
class Player(db.Model):
# ...
# Every match has multiple entries here (as many 1 for
# each player-in-match entry). This will make retrieval
# slower, but more-correct (it is "normalized" now)
class PlayersInMatches(db.Model):
player=db.ReferenceProperty(Player)
match=db.ReferenceProperty(Match)
isCurrent=db.BooleanProperty()