Маршрутизация Django Db

Я пытаюсь запустить приложение Django с двумя db (1 master, 1 read replica). Моя проблема в том, что если я попытаюсь прочитать сразу после записи, то код взрывается. Например:

  • p = Product.objects.create ()
    1. Product.objects.get (ID = p.id)

ИЛИ

    1. Если пользователь перенаправляется на страницу сведений о продукте

Код работает быстрее, чем прочитанная реплика. И если операция чтения использует реплику, код выходит из строя, потому что он не обновлялся вовремя.

Есть ли способ избежать этого? Например, db для чтения выбирается по запросу вместо операции?

Мой маршрутизатор идентичен документации Django:

import random class PrimaryReplicaRouter(object): def db_for_read(self, model, **hints): """ Reads go to a randomly-chosen replica. """ return random.choice(['replica1', 'replica2']) def db_for_write(self, model, **hints): """ Writes always go to primary. """ return 'primary' def allow_relation(self, obj1, obj2, **hints): """ Relations between objects are allowed if both objects are in the primary/replica pool. """ db_list = ('primary', 'replica1', 'replica2') if obj1._state.db in db_list and obj2._state.db in db_list: return True return None def allow_migrate(self, db, app_label, model_name=None, **hints): """ All non-auth models end up in this pool. """ return True 

3 Solutions collect form web for “Маршрутизация Django Db”

В зависимости от размера данных и приложения я бы справился с этим одним из следующих способов:

  1. Фиксирование базы данных:

Расширьте свой маршрутизатор базы данных, чтобы разрешить функции привязки к конкретным базам данных. Например:

 from customrouter.pinning import use_master @use_master def save_and_fetch_foo(): ... 

Хороший пример этого можно увидеть в django-multidb-router . Конечно, вы можете просто использовать этот пакет.

  1. Используйте диспетчер модели для маршрутизации запросов к конкретным базам данных .

     class MyManager(models.Manager): def get_queryset(self): qs = CustomQuerySet(self.model) if self._db is not None: qs = qs.using(self._db) return qs 
  2. Напишите промежуточное программное обеспечение, которое будет автоматически направлять ваши запросы на master / slave. В принципе, такой же, как метод пиннинга, но вы не укажете, когда нужно запускать запросы GET против master.

Решил его:

 class Model(models.Model): objects = models.Manager() -> objects only access master sobjects = ReplicasManager() -> sobjects access either master and replicas class Meta: abstract = True -> so django doesn't create a table 

чтобы каждая модель расширила этот вариант вместо моделей. Моделяйте, а затем используйте объекты или объекты, хочу ли я получить доступ только к мастеру или если вы хотите получить доступ к мастеру или репликам

IN master replica conf для новых данных потребуется несколько миллисекунд для репликации данных на всех других серверах / базе данных реплик.

поэтому всякий раз, когда вы пытались читать после записи, это не дает вам правильного результата.

Вместо чтения из реплики вы можете использовать мастер для чтения сразу после записи, используя ключевое слово using('primary') с вашим запросом на получение.

  • Найти объект в списке, который имеет атрибут, равный некоторому значению (которое соответствует любому условию)
  • Django i18n найти поддерживаемые языки
  • Пользовательский шаблон django admin для конкретной модели
  • Передача аргументов в представления в Django из ограниченного выбора
  • Как запустить тестовую базу Django только в памяти?
  • Как включить аннотацию в строку JSON?
  • Django: Как создать форму множественного выбора?
  • Класс Django: как передать дополнительные параметры методу as_view?
  • Оркестр Django получает последние данные для каждой группы
  • Django 1.9 не может найти newapp
  • PyCharm не может найти правильные пути, если я открою каталог, который не является корнем Django
  • Python - лучший язык программирования в мире.