Die hints
Parameter entworfen, um Ihre Datenbank-Router, um zu entscheiden, wo es sollte seine Daten lesen oder schreiben. Es kann sich mit zukünftigen Versionen von Python entwickeln, aber für den Moment gibt es nur eine Art von Hinweis, die vom Django-Framework gegeben werden kann, und das ist die instance
, an der es arbeitet.
schrieb ich diese sehr einfache Datenbank-Router zu sehen, was Django tut:
# routers.py
import logging
logger = logging.getLogger("my_project")
class DebugRouter(object):
"""A debugging router"""
def db_for_read(self, model, **hints):
logger.debug("db_for_read %s" % repr((model, hints)))
return None
def db_for_write(self, model, **hints):
logger.debug("db_for_write %s" % repr((model, hints)))
return None
def allow_relation(self, obj1, obj2, **hints):
logger.debug("allow_relation %s" % repr((obj1, obj2, hints)))
return None
def allow_syncdb(self, db, model):
logger.debug("allow_syncdb %s" % repr((db, model)))
return None
du erklären in settings.py
:
DATABASE_ROUTERS = ["my_project.routers.DebugRouter"]
sicher Ausgang Debug-Ausgabe richtig konfiguriert ist (zum Beispiel Make-Protokollierung zu stderr):
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
[...some other handlers...]
'stderr': {
'level': 'DEBUG',
'class': 'logging.StreamHandler'
}
},
'loggers': {
[...some other loggers...]
'my_project': {
'handlers': ['stderr'],
'level': 'DEBUG',
'propagate': True,
},
}
}
Dann können Sie ein Django s öffnen Hölle und testen ein paar Anfragen, um zu sehen, welche Daten Ihr Router gegeben wird:
$ ./manage.py shell
[...]
>>> from my_project.my_app.models import User
>>> User.objects.get(pk = 1234)
db_for_read (<class 'my_project.my_app.models.User'>, {})
<User: User object>
>>> user = User.objects.create(name = "Arthur", title = "King")
db_for_write (<class 'my_project.my_app.models.User'>, {})
>>> user.name = "Kong"
>>> user.save()
db_for_write (<class 'my_project.my_app.models.User'>, {'instance':
<User: User object>})
>>>
Wie Sie sehen können, die hints
immer leer ist, wenn keine Instanz verfügbar ist (im Speicher) noch. Daher können Sie Router nicht verwenden, wenn Sie Abfrageparameter (z. B. die ID des Objekts) benötigen, um zu ermitteln, welche Datenbank abgefragt werden soll. Es könnte in Zukunft möglich sein, wenn Django die Abfrage- oder Queryset-Objekte in der dict bereitstellt.
Um Ihre Frage zu beantworten, würde ich sagen, dass Sie jetzt einen benutzerdefinierten Manager erstellen müssen, wie von Aaron Merriam vorgeschlagen. Das Überschreiben der create
-Methode reicht jedoch nicht aus, da Sie auch ein Objekt in der entsprechenden Datenbank abrufen müssen. So etwas wie dies funktionieren könnte (noch nicht geprüft):
class CustomManager(models.Manager)
def self.find_database_alias(self, pk):
return #... implement the logic to determine the shard from the pk
def self.new_object_database_alias(self):
return #... database alias for a new object
def get(self, *args, **kargs):
pk = kargs.get("pk")
if pk is None:
raise Exception("Sharded table: you must provide the primary key")
db_alias = self.find_database_alias(pk)
qs = self.get_query_set().using(db_alias)
return qs.get(*args, **kargs)
def create(self, *args, **kwargs):
db_alias = self.new_object_database_alias()
qs = super(CustomManager, self).using(db_alias)
return qs.create(*args, **kwargs)
class ModelA(models.Model):
objects = CustomManager()
Prost
interessanter Link: http://groups.google.com/group/django-developers/msg/078099f199bdfb79?pli=1 – SingleNegationElimination
Hallo Ich bin mir nicht ganz sicher, was Sie vorhaben. Könnten Sie bitte bestimmte Codebeispiele geben? – MiniQuark