跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • Django 更新一条可能不存在的特定数据是 Get 性能好还是 Filter 好
未分類
4 2 月 2021

Django 更新一条可能不存在的特定数据是 Get 性能好还是 Filter 好

Django 更新一条可能不存在的特定数据是 Get 性能好还是 Filter 好

資深大佬 : Phishion 6

我想优化一下性能,但是有一个地方有 2 种写法,我不知道哪种好一点,就是比如有条数据进来,我要先判断这条数据在不在,如果在就更新,不在就直接新建一条

伪代码如下:

方法 1 )

try:     article = Article.objects.get(id=9999)     触发:更新逻辑 except:     触发:新建逻辑 

方法 2 )

article = Article.objects.filter(id=9999) if article.exists():     exist_article = article[0]     触发:更新逻辑 else:     触发:新建逻辑 

感觉方法 1 有点奇怪,但是似乎就访问一次数据库,方法二啰嗦一点,不知道有没有老鸟能提供帮助?

大佬有話說 (19)

  • 資深大佬 : wuwukai007

    get_or_create

  • 資深大佬 : youngce

    Article.objects.update_or_create() ?

  • 主 資深大佬 : Phishion

    @wuwukai007 请问,这种分装好的底层又是怎么实现的呢?

  • 資深大佬 : renmu123

    1 比较符合 Python 哲学

  • 主 資深大佬 : Phishion

    @wuwukai007
    我看它文档里面还真是 try 出来的,真原始啊

  • 資深大佬 : zeroDev

    应该用 try except 结构,避免判断
    参考 Python 官方文档 https://docs.python.org/3.6/glossary.html#term-eafp

  • 資深大佬 : zeroDev

    @Phishion try 就避免了很多条件判断,写 Python 本身就是为了快速开发嘛

  • 主 資深大佬 : Phishion

    @zeroDev 好的 我瞧瞧

  • 主 資深大佬 : Phishion

    @zeroDev 我一直潜意识认为报错会有额外的性能开销,所以就感觉用 try 处理正常业务逻辑很奇怪

  • 資深大佬 : wuwukai007

    你可以这样理解,如果存在的可能新远远大于 不存在,那么使用 try 的性能不就会搞的多吗,不用 try,每次都要判断

  • 主 資深大佬 : Phishion

    @wuwukai007 有道理,谢谢!

  • 資深大佬 : Geek981108

    文档如是说:
    update_or_create()
    update_or_create(defaults=None, **kwargs)
    A convenience method for updating an object with the given kwargs, creating a new one if necessary. The defaults is a dictionary of (field, value) pairs used to update the object. The values in defaults can be callables.

    Returns a tuple of (object, created), where object is the created or updated object and created is a boolean specifying whether a new object was created.

    The update_or_create method tries to fetch an object from database based on the given kwargs. If a match is found, it updates the fields passed in the defaults dictionary.

    This is meant as a shortcut to boilerplatish code. For example:

    defaults = {‘first_name’: ‘Bob’}
    try:
    obj = Person.objects.get(first_name=’John’, last_name=’Lennon’)
    for key, value in defaults.items():
    setattr(obj, key, value)
    obj.save()
    except Person.DoesNotExist:
    new_values = {‘first_name’: ‘John’, ‘last_name’: ‘Lennon’}
    new_values.update(defaults)
    obj = Person(**new_values)
    obj.save()
    This pattern gets quite unwieldy as the number of fields in a model goes up. The above example can be rewritten using update_or_create() like so:

    obj, created = Person.objects.update_or_create(
    first_name=’John’, last_name=’Lennon’,
    defaults={‘first_name’: ‘Bob’},
    )
    For detailed description how names passed in kwargs are resolved see get_or_create().

    As described above in get_or_create(), this method is prone to a race-condition which can result in multiple rows being inserted simultaneously if uniqueness is not enforced at the database level.

    Like get_or_create() and create(), if you’re using manually specified primary keys and an object needs to be created but the key already exists in the database, an IntegrityError is raised.

  • 資深大佬 : lixuda

    我用这样,不知道性能好不好
    article = Article.objects.filter(id=9999).first()
    if(article):

  • 主 資深大佬 : Phishion

    @lixuda 我觉得用它封装好的性能最好,判断太多代码也显得不整洁

  • 資深大佬 : lixuda

    @Phishion 看错了,是更新逻辑,update_or_create

  • 資深大佬 : Austaras

    有的数据库支持 upsert

  • 資深大佬 : chaleaoch

    你看源码,其实这俩逻辑差不多. get 里面就是 filter + try catch

  • 資深大佬 : nonduality

    你的方法 2 会引发两次查询,优化文档经常提到不要滥用 exists():如果后续仍需要使用到对象数据,就无须用 exists()去判断对象存在与否。

    用 #13 的方法也可以。

  • 主 資深大佬 : Phishion

    @nonduality
    @chaleaoch
    @lixuda
    感谢提供指导!

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具