Situation
Django Proxy-Modell auf andere Datenbank
Wir haben ein paar verschiedene Anwendungen, die Tickets von einem Ticket-Support-System für verschiedene Arten von Funktionalität verwenden.
Zunächst haben wir eine Anwendung, die ein paar Modelle, die die Modelle unseres Ticket-Support-System Kayako darstellen. Diese Anwendung sollte nichts über andere Anwendungen wissen, die sie verwenden, und sollte so allgemein wie möglich bleiben. Da diese Anwendung vorhandene Tabellen von Kayako verwendet, läuft sie auf derselben Datenbank. Nennen wir diese Anwendung kayakodb
.
Eine Anwendung verbindet Kunden aus unserer Kundendatenbank mit Tickets im Ticket-Support-System. Zuvor verfügte dieses System über eine eigene Darstellung der Tickets in unserem Ticket-Support-System, indem es mithilfe einer von kayakodb
bereitgestellten API nach Tickets suchte. Es verwendete dann diese Darstellung von Tickets, um Kunden und Domains zu verknüpfen. Dies war jedoch zu komplex und nicht sehr logisch. Daher haben wir uns dafür entschieden, das Modell auf ein Proxy-Modell umzustellen und die Modelle, die die Links zu Kunden und Domains darstellen, auf kayakodb
zu verschieben. Nennen wir diese Anwendung sidebar
.
Eine weitere, neue Anwendung, zeigt die Tickets aus dem Ticket-Support-System in einer klaren Übersicht neben Anrufen, so dass unsere Support-Abteilung leicht sehen kann, welche Anrufe und Tickets zu welchen Kunden gehören. Dieses System verfügt über ein Proxy-Modell für das Proxy-Modell sidebar
, da einige der Funktionen, die vom sidebar
-Modell bereitgestellt werden, auch für diese Anwendung neben einigen anderen, die das neue Proxy-Modell deklariert, erforderlich sind. Nennen wir dieses Projekt WOW
.
Die Anwendungen sidebar
und WOW
sind beide Teil desselben Projekts/Repositorys. Wir nennen dieses Repository Coneybeach
, das eine eigene Datenbank hat. kayakodb
ist jedoch ein völlig unabhängiges Projekt. Es ist in Coneybeach
über eine Anforderungsdatei enthalten, die wir über pip
installieren.
Problem
Wenn Migrationen für die neue Einrichtung zu schaffen Django einen Proxy-Modell Migration für die installierte
kayakodb
was natürlich ist erstellt, ein no go. Jedes Mal, wenn wir eine neue Version von
kayakodb
installieren würden, würde diese Migration überschrieben. Ganz zu schweigen von der Tatsache, dass
kayakodb
nichts darüber wissen sollte, welche Modelle davon Gebrauch machen.
-Code
Das
Ticket
Modell innerhalb
kayakodb
:
class Ticket(models.Model):
"""
This model is a representation of the data stored in the "kayako" database table "swtickets". Minus a lot of stuff
we don't use. If you add a field make sure it has the same name as the field in kayako.swtickets.
"""
# Fields, functions and manager etc.
class Meta:
db_table = 'swtickets'
managed = False
Der SidebarTicket
Proxy-Modell innerhalb sidebar
:
from kayakodb.models import Ticket
class SidebarTicket(Ticket):
class Meta:
# Since this class is a wrapper we don't want to create a table for it. We only want to access the original
# model as we always do, but provide a different interface (when it comes to functions). Proxy models allow us
# to do this: https://docs.djangoproject.com/en/1.10/topics/db/models/#proxy-models
proxy = True
# Don't look for this model in the sidebar tables, but in the kayakodb tables.
app_label = 'kayakodb'
# Some extra functions
The Contact
Klasse TicketWrapper
erbt von (wie von Hynekc angefordert er).Dieses Modell wird als Basismodell verwendet für TicketWrapper
und ein anderes Modell Anrufe darstellt (obwohl gibt es keine Probleme mit diesem Modell soweit mir bekannt):
class Contact(models.Model):
type = None
class Meta:
abstract = True
def __getattr__(self, attr):
if attr in ['customers', 'add_customer_id', 'remove_all_customers', 'byters', 'domainnames', 'add_domain_name',
'remove_domain_name', 'add_text', 'remove_text', 'texts', 'creation_date', 'add_tag', 'get_tags',
'remove_tag', 'identifier']:
raise NotImplementedError('You should implement {}'.format(attr))
raise AttributeError(attr)
Der TicketWrapper
Proxy-Modell innerhalb WOW
:
from sidebar.models import SidebarTicket
class TicketWrapper(Contact, SidebarTicket):
class Meta:
# Since this class is a wrapper we don't want to create a table for it. We only want to access the original
# model as we always do, but provide a different interface (when it comes to functions). Proxy models allow us
# to do this: https://docs.djangoproject.com/en/1.10/topics/db/models/#proxy-models
proxy = True
# Don't look for this model in the WOW database, but in the kayakodb database.
app_label = 'kayakodb'
# Some extra functions
Was haben versucht, ich
- ich habe versucht, nicht th Angabe e
app_label
für beide Proxy-Modelle. Dadurch werden zwar korrekte Migrationen erstellt, die Proxymodelle werden jedoch nach dem Modellkayakodb.Ticket
in der Coneybeach-Datenbank gesucht. - Ich habe versucht,
abstract = True
für die Unterklassen zu spezifizieren, war aber nicht sicher, dass dies der war, weil ich noch in der Lage sein möchte, den Manager für die Modelle zu verwenden. - Ich überlegte, die Migration, die derzeit erstellt wird, auf das eigentliche
kayakodb
Projekt zu verschieben, aber ich denke nicht, dass dies eine gute Lösung ist.kayakodb
sollte nichts über die Implementierungen seiner Modelle wissen oder wo sie verwendet werden. ./manage.py check
gibt 0 Probleme zurück.
Frage
Wie kann ich einen Proxy-Modell für ein Modell erstellen, die in einer anderen Datenbank oder das Projekt sich befindet?
bearbeiten
Nach dem
kayakodb.Ticket
Modell versucht das
WOW
Projekt nicht verwaltet werden Einstellung in
kayakodb
eine Migration für
alle Modelle zu erstellen. Ergebnis:
Migrations for 'sidebar':
0004_auto_20170116_1210.py:
- Delete model Ticket
Migrations for 'kayakodb':
0001_initial.py:
- Create model Staff
- Create model Tag
- Create model Ticket
- Create model TicketPost
- Create model TicketTag
- Create model TicketCustomer
- Create model TicketDomain
- Create proxy model SidebarTicket
- Alter unique_together for ticketdomain (1 constraint(s))
- Alter unique_together for ticketcustomer (1 constraint(s))
- Create proxy model TicketWrapper
@ e4c5 Ja, das weiß ich. Das ist nett und alles, aber wenn es von Bedeutung ist, wenn es überschrieben wird. – Bono
Sie sagen es selbst "Das liegt daran, dass das Proxy-Modell möglicherweise von einem anderen Modell in einer zukünftigen Migration verwendet wird." Warum würde es sonst stören, eine Migration zu erstellen, wenn sie danach einfach weggeworfen werden kann? – Bono
Du hast mich dort !! Zurückziehen enger Abstimmung. – e4c5