Django ORM: caching and manipulating ForeignKey objects

后端 未结 2 1879
鱼传尺愫
鱼传尺愫 2021-02-06 08:13

Consider the following skeleton of a models.py for a space conquest game:

class Fleet(models.Model):
    game = models.ForeignKey(Game, related_name=\'planet_set         


        
2条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2021-02-06 08:39

    Django's ORM does not implement an identity map (it's in the ticket tracker, but it isn't clear if or when it will be implemented; at least one core Django committer has expressed opposition to it). This means that if you arrive at the same database object through two different query paths, you are working with different Python objects in memory.

    This means that your design (load everything into memory at once, modify a lot of things, then save it all back at the end) is unworkable using the Django ORM. First because it will often waste lots of memory loading in duplicate copies of the same object, and second because of "overwriting" issues like the one you're running into.

    You either need to rework your design to avoid these issues (either be careful to work with only one QuerySet at a time, saving anything modified before you make another query; or if you load several queries, look up all relations manually, don't ever traverse ForeignKeys using the convenient attributes for them), or use an alternative Python ORM that implements identity map. SQLAlchemy is one option.

    Note that this doesn't mean Django's ORM is "bad." It's optimized for the case of web applications, where these kinds of issues are rare (I've done web development with Django for years and never once had this problem on a real project). If your use case is different, you may want to choose a different ORM.

提交回复
热议问题