- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我正在寻找其他尝试使用数据库级隔离构建 Multi-Tenancy Django 应用程序的工作代码和想法。
更新/解决方案:我在一个新的开源项目中解决了这个问题:参见 django-db-multitenant
我的目标是根据请求主机名或请求路径(例如 foo.example.com/
将 Django 连接设置为使用数据库 foo
,而 bar.example.com/
使用数据库 bar
)。
我知道一些现有的 Django Multi-Tenancy 解决方案:
SET search_path
命令发送到数据库。不幸的是,它是 Postgres 特有的,我被 MySQL 困住了。(id,tenant_id)
而不是 (id)
索引。我尝试过但不喜欢这种方法,原因有很多:它使应用程序更加复杂,可能导致难以发现的错误,而且它不提供数据库级别的隔离。到目前为止,我最好的想法是执行 django-tenant-schemas
之类的操作:在第一个中间件中,获取 django.db.connection
并调整数据库选择而不是架构。我还没有完全考虑到这对于池/持久连接意味着什么
我追求的另一个死胡同是特定于租户的表前缀:除了我需要它们是动态的之外,即使是全局表前缀在 Django 中也不容易实现(参见 rejected ticket 5000 等)。
最后,Django multiple database support允许您定义多个命名数据库,并根据实例类型和读/写模式在它们之间多路复用。没有帮助,因为没有工具可以根据每个请求选择数据库。
有人做过类似的事情吗?如果有,您是如何实现的?
最佳答案
我已经做了最接近第 1 点的类似操作,但没有使用中间件来设置默认连接,而是使用了 Django 数据库路由器。如果每个请求需要,这允许应用程序逻辑使用多个数据库。为每个查询选择合适的数据库取决于应用程序逻辑,这是这种方法的一大缺点。
通过此设置,所有数据库都列在 settings.DATABASES
中,包括可能在客户之间共享的数据库。每个客户特定的模型都放置在具有特定应用标签的 Django 应用中。
例如。下面的类定义了一个存在于所有客户数据库中的模型。
class MyModel(Model):
....
class Meta:
app_label = 'customer_records'
managed = False
一个数据库路由器被放置在 settings.DATABASE_ROUTERS
链中,以通过 app_label
路由数据库请求,如下所示(不是完整示例):
class AppLabelRouter(object):
def get_customer_db(self, model):
# Route models belonging to 'myapp' to the 'shared_db' database, irrespective
# of customer.
if model._meta.app_label == 'myapp':
return 'shared_db'
if model._meta.app_label == 'customer_records':
customer_db = thread_local_data.current_customer_db()
if customer_db is not None:
return customer_db
raise Exception("No customer database selected")
return None
def db_for_read(self, model, **hints):
return self.get_customer_db(model, **hints)
def db_for_write(self, model, **hints):
return self.get_customer_db(model, **hints)
关于这个路由器的特殊部分是 thread_local_data.current_customer_db()
调用。在执行路由器之前,调用者/应用程序必须已经在 thread_local_data
中设置了当前客户数据库。为此,可以使用 Python 上下文管理器来推送/弹出当前客户数据库。
配置完所有这些后,应用程序代码如下所示,其中 UseCustomerDatabase
是一个上下文管理器,用于将当前客户数据库名称推送/弹出到 thread_local_data
中,因此thread_local_data.current_customer_db()
将在最终命中路由器时返回正确的数据库名称:
class MyView(DetailView):
def get_object(self):
db_name = determine_customer_db_to_use(self.request)
with UseCustomerDatabase(db_name):
return MyModel.object.get(pk=1)
这已经是一个相当复杂的设置了。它有效,但我会尝试总结一下我认为的优点和缺点:
优势
USE db;
语句。缺点
建议
如果您想要灵活的数据库访问,我建议使用 Django 的数据库路由器。使用中间件或 View Mixin,它会根据请求参数自动设置用于连接的默认数据库。您可能不得不求助于线程本地数据来存储要使用的默认数据库,以便当路由器被击中时,它知道要路由到哪个数据库。这允许 Django 使用其现有的持久连接到数据库(如果需要,可以驻留在不同的主机上),并根据请求中设置的路由选择要使用的数据库。
这种方法还有一个优点,即如果需要,可以使用 QuerySet using()
覆盖查询的数据库。用于选择默认数据库以外的数据库的函数。
关于mysql - Multi-Tenancy Django 应用程序 : altering database connection per request?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16721051/
我知道这不是什么大问题,但还是让我觉得很痒。 我有一个 SQL Server 2005 脚本来创建新的数据表、约束、更改一些表以添加列、更改过程以将表更改考虑在内等。 一切正常,直到脚本遇到我的 AL
我需要一个包含三列的数据框:i、j(改变)和 k(j 的改变)。我有一个邻接矩阵(下面的示例)。从那里我可以获得一个图形对象并提取边缘列表。我如何操作数据以获得类似于下面的 WANT 数据框的输出?
假设我有这个 SQL 语句: ALTER TABLE dbo.[tbl] ALTER COLUMN col1 varchar(300) ALTER TABLE dbo.[tbl] ALTER COLU
我在表中有一列,因此它不再是 NVARCHAR(256),而是 NVARCHAR(MAX)。我知道执行此操作的命令 (ALTER TABLE ALTER COLUMN NVARCHAR(MAX))。我
我在表中有一列,因此它不再是 NVARCHAR(256),而是 NVARCHAR(MAX)。我知道执行此操作的命令 (ALTER TABLE ALTER COLUMN NVARCHAR(MAX))。我
假设我有这两个 ALTER TABLE: ALTER TABLE tableName ADD COLUMN colName INT(11) AFTER colName2 ALTER TABLE tab
我正在尝试扩展 IdentityUser 类。我添加了一个新类 ApplicationUser 并继承了 IdentityUser 类。迁移已成功添加,但在更新数据库时,出现错误“对象 'PK_Asp
我想将 sql server 2005 表中的列修改为 IDENTITY(1,1) 顺便说一句,该表是空的,要更改的列是主键。 该列也是另外两个表的外键。 谷歌搜索后我发现你不能使用Alter tab
这是我要实现的目标:我在列表中有四个按钮,每个按钮都有白色背景和独特的彩色边框。单击一个按钮时,其背景颜色将与其边框颜色相同。单击第二个按钮时,第一个按钮恢复正常,第二个按钮的背景填充第二个按钮的边框
我在 clickhouse 有一张 table ,比如“my_table”,它有复制品(my_table_rep1,...)。我需要添加一个列,类型为 float64,默认值 (-1)。 我该怎么做?
alter FUNCTION [Kuri].[fnGetAge](@kuri_cust_Id int,@amt decimal) RETURNS SMALLINT AS BEGIN D
我试图确保当我 mysqldump 数据库时约束在执行以下查询后按数字顺序排列。当我在没有 AFTER 的情况下进行转储(这不起作用)时,它显示 phppos_sales_ibfk_3 作为第一个约束
我有两个表:cleanup 和 uniqueEntries。它们都有一个自动递增的id作为主键。 uniqueEntries 的表结构来自 cleanup,如下所示: $sql = "CREATE T
我有一个包含以下数据和结构的表: Date Analyst Start Time Stop Time 4/2/2018 Bill Smith 7:00
This question already has answers here: Error renaming a column in MySQL
是否可以更改表的多(复合)列键? 示例表: CREATE TABLE `test_abc` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `
我尝试执行 oracle alter session 查询以更改语言设置,但失败并出现错误“ORA-01036:非法变量名称/编号”。 preparedStatement = connection.p
我正在与一位客户合作,他希望大型数据库中的每个表的每条记录都有历史数据,并且为了美观,希望这些列位于每个表的末尾。例如: 表名 主键 数据列 历史专栏 所以我的问题是,是否有一个 SQL 命令可以将列
我正在尝试更改 SQL Server 2000 更新触发器,但它一直挂着、挂着、挂着。为什么会发生这种情况,我该怎么做才能解决这个问题?这是一个长触发器,这可能是为什么? 触发代码较长,简化如下: A
我正在将我的 mysql 数据库表从 id (auto) 更改为 uid。 ALTER TABLE companies DROP PRIMARY KEY; ALTER TABLE companies
我是一名优秀的程序员,十分优秀!