Maison > interface Web > js tutoriel > Introduction à la façon dont Django utilise plusieurs méthodes de base de données

Introduction à la façon dont Django utilise plusieurs méthodes de base de données

巴扎黑
Libérer: 2017-09-07 10:17:08
original
1576 Les gens l'ont consulté

Certains projets peuvent impliquer l'utilisation de plusieurs bases de données, et la méthode est très simple. Ensuite, cet article vous présentera la méthode d'utilisation de plusieurs bases de données dans Django. Les amis qui en ont besoin peuvent s'y référer

Certains projets peuvent impliquer l'utilisation de plusieurs bases de données. La méthode est très simple.

1. Définissez BASE DE DONNÉES dans les paramètres

Par exemple, si vous souhaitez utiliser deux bases de données :


DATABASES = {
  'default': {
    'NAME': 'app_data',
    'ENGINE': 'django.db.backends.postgresql',
    'USER': 'postgres_user',
    'PASSWORD': 's3krit'
  },
  'users': {
    'NAME': 'user_data',
    'ENGINE': 'django.db.backends.mysql',
    'USER': 'mysql_user',
    'PASSWORD': 'priv4te'
  }
}
Copier après la connexion

De cette manière, deux bases de données sont identifiées, l'une avec l'alias par défaut et l'autre avec l'alias utilisateur. L'alias de la base de données peut être déterminé arbitrairement.

L'alias par défaut est spécial Lorsqu'un Modèle n'est pas spécifiquement sélectionné dans la route, la base de données par défaut est utilisée par défaut.

Bien sûr, la valeur par défaut peut également être définie sur vide :


DATABASES = {
  'default': {},
  'users': {
    'NAME': 'user_data',
    'ENGINE': 'django.db.backends.mysql',
    'USER': 'mysql_user',
    'PASSWORD': 'superS3cret'
  },
  'customers': {
    'NAME': 'customer_data',
    'ENGINE': 'django.db.backends.mysql',
    'USER': 'mysql_cust',
    'PASSWORD': 'veryPriv@ate'
  }
}
Copier après la connexion

De cette façon, comme il n'y a pas de base de données par défaut, vous devez définir à tous les modèles, y compris Le modèle de la bibliothèque tierce est utilisé pour effectuer la sélection de routage de la base de données.

2. Spécifiez app_label


class MyUser(models.Model):
  ...
  class Meta:
    app_label = 'users'
Copier après la connexion

pour le modèle qui doit effectuer la sélection de base de données. 3. Écrivez les routeurs de base de données<. 🎜>

Database Router est utilisé pour déterminer quelle base de données un modèle utilise. Il définit principalement les quatre méthodes suivantes :

db_for_read(model, **hints)

Spécifie quelle base de données le modèle utilise pour lire.

db_for_write(model, **hints)

Spécifie dans quelle base de données le modèle doit être écrit.

allow_relation(obj1, obj2, **hints)

Déterminez si obj1 et obj2 peuvent être associés, principalement utilisés pour les clés étrangères et plusieurs à plusieurs opérations.

allow_migrate(db, app_label, model_name=None, **hints)

Détermine si l'opération de migration peut être exécutée sur la base de données avec l'alias db.

Un exemple complet :

Paramètres de la base de données :


DATABASES = {
  &#39;default&#39;: {},
  &#39;auth_db&#39;: {
    &#39;NAME&#39;: &#39;auth_db&#39;,
    &#39;ENGINE&#39;: &#39;django.db.backends.mysql&#39;,
    &#39;USER&#39;: &#39;mysql_user&#39;,
    &#39;PASSWORD&#39;: &#39;swordfish&#39;,
  },
  &#39;primary&#39;: {
    &#39;NAME&#39;: &#39;primary&#39;,
    &#39;ENGINE&#39;: &#39;django.db.backends.mysql&#39;,
    &#39;USER&#39;: &#39;mysql_user&#39;,
    &#39;PASSWORD&#39;: &#39;spam&#39;,
  },
  &#39;replica1&#39;: {
    &#39;NAME&#39;: &#39;replica1&#39;,
    &#39;ENGINE&#39;: &#39;django.db.backends.mysql&#39;,
    &#39;USER&#39;: &#39;mysql_user&#39;,
    &#39;PASSWORD&#39;: &#39;eggs&#39;,
  },
  &#39;replica2&#39;: {
    &#39;NAME&#39;: &#39;replica2&#39;,
    &#39;ENGINE&#39;: &#39;django.db.backends.mysql&#39;,
    &#39;USER&#39;: &#39;mysql_user&#39;,
    &#39;PASSWORD&#39;: &#39;bacon&#39;,
  },
}
Copier après la connexion
Si vous souhaitez obtenir les effets suivants :

La lecture et l'écriture du modèle dont app_label est auth sont terminées dans auth_db, le reste de l'écriture du modèle est terminé dans le primaire et la lecture est terminée de manière aléatoire dans réplique1 et réplique2.

auth :


class AuthRouter(object):
  """
  A router to control all database operations on models in the
  auth application.
  """
  def db_for_read(self, model, **hints):
    """
    Attempts to read auth models go to auth_db.
    """
    if model._meta.app_label == &#39;auth&#39;:
      return &#39;auth_db&#39;
    return None
  def db_for_write(self, model, **hints):
    """
    Attempts to write auth models go to auth_db.
    """
    if model._meta.app_label == &#39;auth&#39;:
      return &#39;auth_db&#39;
    return None
  def allow_relation(self, obj1, obj2, **hints):
    """
    Allow relations if a model in the auth app is involved.
    """
    if obj1._meta.app_label == &#39;auth&#39; or \
      obj2._meta.app_label == &#39;auth&#39;:
      return True
    return None
  def allow_migrate(self, db, app_label, model_name=None, **hints):
    """
    Make sure the auth app only appears in the &#39;auth_db&#39;
    database.
    """
    if app_label == &#39;auth&#39;:
      return db == &#39;auth_db&#39;
    return None
Copier après la connexion
De cette façon, la lecture et l'écriture du Modèle dont app_label est auth se terminent dans auth_db, et les associations sont autorisées . Migrate est uniquement dans la base de données auth_db.

Le reste :


import random
class PrimaryReplicaRouter(object):
  def db_for_read(self, model, **hints):
    """
    Reads go to a randomly-chosen replica.
    """
    return random.choice([&#39;replica1&#39;, &#39;replica2&#39;])
  def db_for_write(self, model, **hints):
    """
    Writes always go to primary.
    """
    return &#39;primary&#39;
  def allow_relation(self, obj1, obj2, **hints):
    """
    Relations between objects are allowed if both objects are
    in the primary/replica pool.
    """
    db_list = (&#39;primary&#39;, &#39;replica1&#39;, &#39;replica2&#39;)
    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
Copier après la connexion
De cette façon, la lecture se fait de manière aléatoire dans la réplique1 et la réplique2, et l'écriture utilise le primaire.

Enfin, définissez-le dans les paramètres :


DATABASE_ROUTERS = [&#39;path.to.AuthRouter&#39;, &#39;path.to.PrimaryReplicaRouter&#39;]
Copier après la connexion
et c'est tout.

Lors de l'exécution d'une opération de migration :


$ ./manage.py migrate
$ ./manage.py migrate --database=users
Copier après la connexion
L'opération de migration opère par défaut sur la base de données par défaut. Pour opérer sur d'autres bases de données, vous pouvez utiliser. Option --database, suivie de l'alias de la base de données.

En conséquence, les commandes dbshell, dumpdata et loaddata ont toutes l'option --database.

Vous pouvez également sélectionner manuellement l'itinéraire :

Requête :


>>> # This will run on the &#39;default&#39; database.
>>> Author.objects.all()
>>> # So will this.
>>> Author.objects.using(&#39;default&#39;).all() 
>>> # This will run on the &#39;other&#39; database.
>>> Author.objects.using(&#39;other&#39;).all()
Copier après la connexion
Enregistrer :


>>> my_object.save(using=&#39;legacy_users&#39;)
Copier après la connexion
Déplacer :


>>> p = Person(name=&#39;Fred&#39;)
>>> p.save(using=&#39;first&#39;) # (statement 1)
>>> p.save(using=&#39;second&#39;) # (statement 2)
Copier après la connexion
Le code ci-dessus posera des problèmes lorsque p est enregistré pour la première fois dans la première base de données, il générera par défaut une clé primaire de sorte que lors de l'enregistrement dans la deuxième base de données, p ait déjà une clé primaire. Cette clé primaire ne posera pas de problèmes si elle n'est pas utilisée, mais si elle a été utilisée précédemment, les données d'origine seront écrasées. .

Il existe deux solutions :

1. Effacez la clé primaire avant de sauvegarder :


>>> p = Person(name=&#39;Fred&#39;)
>>> p.save(using=&#39;first&#39;)
>>> p.pk = None # Clear the primary key.
>>> p.save(using=&#39;second&#39;) # Write a completely new object.
Copier après la connexion
2. Utilisez force_insert


>>> p = Person(name=&#39;Fred&#39;)
>>> p.save(using=&#39;first&#39;)
>>> p.save(using=&#39;second&#39;, force_insert=True)
Copier après la connexion
pour supprimer :

De quelle base de données l'objet a été obtenu et où supprimer


>>> u = User.objects.using(&#39;legacy_users&#39;).get(username=&#39;fred&#39;)
>>> u.delete() # will delete from the `legacy_users` database
Copier après la connexion
Si vous souhaitez transférer un objet de la base de données Legacy_users vers la base de données new_users :


Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal