gpt4 book ai didi

Django 数据分片

转载 作者:行者123 更新时间:2023-12-04 17:40:48 24 4
gpt4 key购买 nike

我已经使用基于模型的路由方案成功地让我的应用程序在多个数据库上运行。 IE。模型 A 存在于 DB A 上,模型 B 存在于 DB B 上。我现在需要对我的数据进行分片。我正在查看文档,但由于多个数据库服务器上需要存在相同的模型,因此无法确定如何执行此操作。我想有一个标志说新成员的 DB 现在是数据库 X,成员 X-Y 住在数据库 N 等上。

我怎么做?是否使用**提示,这对我来说似乎没有充分记录。

最佳答案

hints参数旨在帮助您的数据库路由器决定应该在哪里读取或写入数据。它可能会随着 Python 的 future 版本而发展,但目前只有一种可能由 Django 框架给出的提示,那就是 instance它正在处理。

我写了这个非常简单的数据库路由器来看看 Django 做了什么:

# 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

您在 settings.py 中声明了这一点:
DATABASE_ROUTERS = ["my_project.routers.DebugRouter"]

确保正确配置日志记录以输出调试输出(例如输出到 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,
},
}
}

然后你可以打开一个 Django shell 并测试一些请求,看看你的路由器得到了什么数据:
$ ./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>})
>>>

如您所见, hints当尚无可用实例(在内存中)时,它始终为空。因此,如果您需要查询参数(例如对象的 id)来确定要查询的数据库,则不能使用路由器。如果 Django 在 hints 中提供 query 或 queryset 对象,将来可能会有可能字典。

因此,为了回答您的问题,我想说现在您必须按照 Aaron Merriam 的建议创建一个自定义管理器。但只覆盖 create方法是不够的,因为您还需要能够在适当的数据库中获取对象。这样的事情可能会起作用(尚未测试):
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()

干杯

关于Django 数据分片,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4481435/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com