Opened 5 years ago

Closed 5 years ago

Last modified 5 years ago

#30690 closed Uncategorized (duplicate)

get_or_create() ignores database router's db_for_read() method

Reported by: Maciej Olko Owned by: nobody
Component: Database layer (models, ORM) Version: 2.2
Severity: Normal Keywords: router, database-router, get_or_create
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

class Foo(models.Model):  # model in `legacy` app
    bar = models.CharField()

class FizRouter:
    @staticmethod
    def db_for_read(model, **hints):
        if model._meta.app_label == 'legacy':
            return 'legacy'
        return 'default'

    @staticmethod
    def db_for_write(model, **hints):
        return 'default'

# file: settings.py
DATABASE_ROUTERS = ['path.FizRouter']

Foo.objects.get_or_create() will hit default database no matter if requested object is in legacy database.
I would assume that we would try to get object from legacy database and create in default if not found.

As far as I'm concerned current behaviour is not documented, IMHO it should be, if current behaviour is desired.

Change History (2)

comment:1 by Simon Charette, 5 years ago

Resolution: duplicate
Status: newclosed

By it's nature of dealing with both read and writes the get_or_create method has to be targeting the write database for reads.

There's a comment in the method definition about it and following the git blame trace leads to this commit.

Closing as duplicate of #16865.

Version 1, edited 5 years ago by Simon Charette (previous) (next) (diff)

comment:2 by Maciej Olko, 5 years ago

I couldn't find the duplicate. Thank you for response.

Note: See TracTickets for help on using tickets.
Back to Top