Comment utiliser django modèles avec des clés étrangères dans différents DBs?
J'ai 2 modèles pour les 2 bases de données différentes:
Les bases de données ont été créés manuellement, mais il devrait rien changer.
class LinkModel(models.Model): # in 'urls' database
id = models.AutoField(primary_key=True)
host_id = models.IntegerField()
path = models.CharField(max_length=255)
class Meta:
db_table = 'links'
app_label = 'testapp'
def __unicode__(self):
return self.path
class NewsModel(models.Model): # in default database
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=50)
link = models.ForeignKey(LinkModel)
class Meta:
db_table = 'news'
app_label = 'test'
def __unicode__(self):
return self.title
Après le code suivant, une erreur soulève
newsItem, created = NewsModel.objects.get_or_create( title="test" )
link = LinkModel.objects.using('urls').get( id=1 )
newsItem.link = link # error!
Cannot assign "<LinkModel: />": instance is on database "default", value is on database "urls"
Pourquoi ne puis-je pas utiliser de clé étrangère et un modèle pour les différentes base de données?
Vous devez vous connecter pour publier un commentaire.
De la croix-base de données des limites
Django ne dispose pas actuellement de fournir un soutien pour les clés étrangères ou plusieurs-à-plusieurs liens couvrant de multiples bases de données. Si vous avez utilisé un routeur pour la partition de modèles à différentes bases de données, d'une clé étrangère et plusieurs-à-plusieurs relations définies par ces modèles doivent être à l'intérieur d'une base de données unique.
Django - limites-de-plusieurs-bases de données
De la difficulté à
Même problème. Bug dans ForeignKey() de la classe.
Dans validate() de la méthode.
Voir le billet
Bug existe dans v1.2, v1.3, v1.4rc1
Solution
Essayer ce patch pour le résoudre.
self.rel.to._meta.db_table
?Le Problème
*Note: ceci est une extension de Vitaly Fadeev la réponse de
En raison d'un désir de maintenir l'intégrité référentielle, Django ne permet pas pour les clés étrangères qui s'étendent sur plusieurs bases de données: https://docs.djangoproject.com/en/dev//topics/db/multi-db/#limitations-of-multiple-databases. Même si cela est souhaité, 99% de toutes les demandes, dans certains cas, il est utile d'être capable de créer une telle association dans l'ORM, même si vous ne pouvez pas assurer l'intégrité référentielle.
Une Solution
J'ai créé un Gist qui utilise la solution proposée ici par Vitaly Fadeev enveloppé comme une sous-classe de la Django champ ForeignKey. Cette solution ne nécessite pas de modifier Django fichiers de Base mais au lieu d'utiliser ce type de champ au lieu de cela, dans le cas que vous en avez besoin.
Exemple D'Utilisation
L'Essentiel
Le résumé est disponible ici: https://gist.github.com/gcko/de1383080e9f8fb7d208
Copié ici pour en faciliter l'accès:
Comme une alternative (un peu hackish tout de même), vous pourriez sous-classe ForeignKey pour vérifier par exemple existence à l'intérieur de la droite db :
puis à peine :
Noter qu'il correspond plus ou moins à le patch que Vitaly mentionne, mais qui ne nécessitent pas de patch django code source.
Après la rupture de ma tête quelques jours, j'ai réussi à obtenir ma Clé Étrangère SUR LA MÊME BANQUE!
Peut être fait une variation sur le FORMULAIRE pour demander une CLÉ ÉTRANGÈRE dans une autre banque!
Tout d'abord, ajoutez une RECHARGE de DOMAINES, à la fois directement (fissure) de mon formulaire, en fonction _init_
app.form.py
l'appel de la Forme à partir de la Vue
app.view.py
Maintenant, le changement dans le Code source de DJANGO
Seuls les champs de type ForeignKey, ManyToManyField et OneToOneField pouvez utiliser le 'aide', donc ajouté un SI ...
django.forms.models.py
ALTER SUIVRE FICHIER
django.db.models.base.py
modifier
pour
Prêt 😀
L'utilisation de plusieurs bases de données rend les choses plus difficile.
Lire: MultipleDB Django
Pour des trucs comme ça au travail, vous devez utiliser la Base de données des Routeurs comme décrit dans le lien que je sache.
Je n'ai jamais utilisé à plusieurs DB installation avec les clés étrangères entre eux, mais c'est là que je voudrais commencer.