2

我有一个基本关系定义如下: db = Database('sqlite', 'test_db.sqlite', create_db=True)

class WOEID(db.Entity):
    woeid      = PrimaryKey(int)
    iso        = Optional(str)
    name       = Required(str)
    language   = Optional(str)
    place_type = Required(str)
    parent_id  = Required(int)
    trends     = Set('Trend')
    ancestry   = Optional(str)

class Trend(db.Entity):
    woeid                = Required(int)
    events               = Optional(str)
    name                 = Required(str)
    promoted_content     = Optional(str)
    query                = Required(str)
    url                  = Required(str)
    location             = Optional(WOEID)

db.generate_mapping(create_tables=True) 

现在,我在用@db_session 修饰的函数中将一些项目添加到WOEID.trends。这按预期工作。现在我尝试通过首先使用读取对象来更新 WOEID.trends

 location = WOEID.get(woeid = some_woeid)

后来我发出

location.trends.clear()

删除旧条目,然后将新条目添加到趋势集中。

在此操作后生成的趋势表中,我添加了项目,但以前的项目(从集合中清除)没有被删除,它们留在数据库中,“位置”字段为空(我猜它们被取消引用)。

我应该如何执行上述操作来读取孤立项?

4

1 回答 1

3

PonyORM 中有两种一对多的关系。第一种关系是关系的一端是,关系Set的另一端是Required。在这种情况下,当您从集合中删除一个项目时,该项目将被删除。例如,我们可以通过以下方式定义两个Article实体Comment

class Article(db.Entity):
    author = Required(User)
    text = Required(str)
    comments = Set('Comment')

class Comment(db.Entity):
    author = Required(User)
    text = Required(str)
    article = Required(Article)

在这种情况下,当您执行时,article.comments.clear()所有评论都将被删除,因为该Comment.article属性是必需的,并且没有文章就不能存在评论。

另一种关系是Comment.article属性定义为Optional

class Comment(db.Entity):
    author = Required(User)
    text = Required(str)
    article = Optional(Article)

在这种情况下,评论可以在没有任何文章的情况下存在,并且当您从Article.comments集合中删除评论时,它仍保留在数据库中,但Comment.article属性值设置为NULL

您可以通过执行以下查询来查找孤立项:

select(c for c in Comment if c.article is None)

或者,等效地

Comment.select(lambda c: c.article is None)

在某些情况下,可能需要将属性定义为Optional,但在从集合中删除项目时执行级联删除。为此,您可以为属性指定cascade_delete选项:Set

class Article(db.Entity):
    author = Required(User)
    text = Required(str)
    comments = Set('Comment', cascade_delete=True)

class Comment(db.Entity):
    author = Required(User)
    text = Required(str)
    article = Optional(Article)

然后,如果您这样做,article.comments.clear()则所有已删除的评论都将从数据库中删除。

于 2015-06-03T11:17:23.723 回答