我一直在判断Django,想知道以下情况是否可能.我已经看过常规的多数据库文档,所以请不要指给我看,因为在我所能理解的范围内没有提到这个用例.如果我错了,我会收回:)

我想要一个主数据库,我的应用程序的大部分模型将驻留在其中,但是其中一个应用程序将需要动态创建数据库,这些将是客户特定的数据库.

数据库路径(我计划使用sqlite)将存储在主数据库中,因此需要更改游标,但模型将保持不变.

我欢迎任何关于如何实现这一点的 idea ?

推荐答案

我将以"You should not edit settings at runtime"开头.

话虽如此,我也遇到了完全相同的问题,我希望 for each 用户创建一个唯一的数据库.这样做的原因是,我为用户提供了保存/访问未存储在我的服务器上的数据库的能力,这需要有多个数据库,因此每个用户都有一个数据库.

此答案不是实现预期目标的推荐方法.我很想听听Django-Guru如何最好地处理这个问题.然而,这是我一直在使用的解决方案,到目前为止它工作得很好.我使用的是sqlite,但是可以很容易地为任何数据库修改它.

总而言之,这是一个过程:

  1. 将新数据库添加到设置(运行时)
  2. 创建一个文件来存储这些设置,以便在重新启动服务器时(在运行时)重新加载
  3. 运行加载保存的设置文件的脚本(每当重新启动服务器时)

现在,如何实现这一点:

1) 首先,当创建一个新用户时,我会在设置中创建一个新数据库.在我看来,这段代码就是创建新用户的地方.

from YOUR_PROJECT_NAME import settings
database_id = user.username #just something unique
newDatabase = {}
newDatabase["id"] = database_id
newDatabase['ENGINE'] = 'django.db.backends.sqlite3'
newDatabase['NAME'] = '/path/to/db_%s.sql' % database_id
newDatabase['USER'] = ''
newDatabase['PASSWORD'] = ''
newDatabase['HOST'] = ''
newDatabase['PORT'] = ''
settings.DATABASES[database_id] = newDatabase
save_db_settings_to_file(newDatabase) #this is for step 2)

此脚本将数据库设置"在运行时"加载到django项目设置中.但是,如果服务器重新启动,该数据库将不再处于设置中.

2) 为了便于在服务器重启时自动重新加载这些设置,我 for each 数据库创建了一个文件,在服务器启动时将加载该文件.创建此文件由函数save_db_settings_to_file执行:

def save_db_settings_to_file(db_settings):
    path_to_store_settings = "/path/to/your/project/YOUR_PROJECT_NAME/database_settings/"
    newDbString = """
DATABASES['%(id)s'] = {
    'ENGINE': '%(ENGINE)s', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
    'NAME': '%(NAME)s',                      # Or path to database file if using sqlite3.
    'USER': '',                      # Not used with sqlite3.
    'PASSWORD': '',                  # Not used with sqlite3.
    'HOST': '',                      # Set to empty string for localhost. Not used with sqlite3.
    'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
}
    """ % db_settings
    file_to_store_settings = os.path.join(path_to_store_settings, db_settings['id'] + ".py")
    write_file(file_to_store_settings, newDbString) #psuedocode for compactness

3)要在服务器启动时实际加载这些设置,我在/path/to/your/project/YOUR_PROJECT_NAME/settings.py的最底部添加了一行,它加载设置文件夹中的每个文件并运行它,其效果是将数据库详细信息加载到设置中.

import settings_manager

然后,import settings_manager将在/path/to/your/project/YOUR_PROJECT_NAME/settings_manager.py加载文件,其中包含以下代码:

from settings import DATABASES
import os

path_to_store_settings = "/path/to/your/project/YOUR_PROJECT_NAME/database_settings/"
for fname in os.listdir(path_to_settings):
    full_path = os.path.join(path_to_settings, fname)
    f = open(full_path)
    content = f.read()
    f.close()
    exec(content) #you'd better be sure that the file doesn't contain anything malicious

请注意,您可以将此代码直接放在settings.py的底部,而不是import语句,但是使用import语句可以保持settings.py的抽象级别一致.

这是加载每个数据库设置的一种方便方法,因为要从设置中删除数据库,您只需删除设置文件,服务器下次重新启动时不会将这些详细信息加载到设置中,并且数据库将不可访问.

正如我所说的,这是可行的,到目前为止,我已经成功地使用了它,但这不是理想的解决方案.如果有人能提供更好的解决方案,我将不胜感激.

它有什么不好的地方:

  • 它明确无视django团队关于在运行时不修改设置的建议.我不知道为什么会给出这样的建议.
  • 它使用exec语句将数据加载到设置中.这应该没问题,但如果你在其中一个文件中得到一些腐败或恶意代码,你将是一只悲伤的Pandas .

请注意,我仍然使用身份验证和会话数据的默认数据库,但是来self 自己的应用程序的所有数据都存储在特定于用户的数据库中.

Django相关问答推荐

如何创建为模型创建信号的Djangodecorator ?

如何在对接合成时创建两个Postgres数据库?

覆盖保存以创建范围的多个对象()

使用自定义的AuthBackend时,无法使用request.user.is_authenticated或@login_required修饰符

Django中用于外键的嵌套循环

如何使用来自另一个字段的信息创建字段

Django 注释(),计数()

是否有 django 模板过滤器来显示百分比?

使用移动应用程序保护通信 [真实性、隐私和完整性]?

获取 Django 中的缓存键列表

(fields.E300) 字段定义与模型的关系,该模型要么未安装,要么是抽象的

Django - 在模板中显示当前日期和时间

如何在终端中切换 Python 版本?

用户组和权限

使用 XMLHttpRequest 提示下载文件

有 Django List View 模型排序吗?

OrderingFilter 没有属性filter_queryset

django:manytomanyfield 和 through 如何出现在 admin 中?

如何查询名称包含python列表中任何单词的模型?

APIView 类和视图集类之间的区别?