3

I'm using the admin search_fields functionality.

The problem: some of my tables are very big. So search is taking forever, and adding extra load on my production database.

As I'm having a follower of my production db, I though a good idea would be to use the follower as a read-only db, especially for those kind of requests.

So I decided to add a 'read-only' db in settings.DATABASES and surcharge ModelAdmin.get_search_results in my admin classes:

def get_search_results(self, request, queryset, search_term):
    queryset, use_distinct = super(ReadOnlyDatabaseAdmin, self)\
        .get_search_results(request, queryset, search_term)

    queryset = queryset.using('read-only')

    return queryset, use_distinct

After this update, I started to get some router errors when trying to set some object as foreign key related object of another object:

Cannot assign "...": the current database router prevents this relation

NB: the read-only database was the same as the default one when I tested and got the aforementioned error, I didn't use the follower yet. I just have set a 'read-only' key in settings.DATABASES, pointing to the same dict as DATABASES['default'].

So the problem is not coming from using a different database, but strictly from the database router.

To give more detail: this error is notably coming from admin actions that are performed when in a admin-search-results page (/admin/app/obj/?q=...).

I figured it's maybe because I replace the queryset object in the method. Maybe this object is actually re-used somewhere else notably in admin actions...? I am currently looking into this.

So I'm interested in:

  • finding the reason of the error
  • and/or finding another way of performing admin search requests on a follower database to offload the main database
lajarre
  • 4,910
  • 6
  • 42
  • 69

2 Answers2

3

I guess the answer to the error is to do instead:

if request.method == 'GET':
    queryset = queryset.using('read-only')

Indeed, the search results are dont with a GET, while the admin actions are done with a POST.

I will have to check this

lajarre
  • 4,910
  • 6
  • 42
  • 69
0

This is not exactly you are looking for How to improved query performance in Django admin search on related fields (MySQL), but it can help to optimize the queries.

Community
  • 1
  • 1
trinchet
  • 6,753
  • 4
  • 37
  • 60