Django多个动态数据库 [英] Django multiple and dynamic databases

查看:134
本文介绍了Django多个动态数据库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在评估django,想知道以下是否可以。我已经查看了常规的多个数据库文档,所以请不要指出我,因为这个用例没有提及我可以做出来。如果我错了,我把它拿回来:)



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



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

我欢迎有任何想法来实现这一点?

解决方案

将打开您不应该在运行时编辑设置



说完了,我有完全相同的问题,我想为每个用户创建一个唯一的数据库。这样做的原因是我提供了用户保存/访问不存储在我的服务器上的数据库的能力,这需要有多个数据库,因此每个用户都有一个。



这个答案不是达到预期目的的推荐方法。我很乐意听到一个django-guru如何最好地解决这个问题。然而,这是一个我一直在使用的解决方案,迄今为止已经运行良好。我正在使用sqlite,但是可以轻松修改任何数据库。



总之,这是一个过程:


  1. 将新数据库添加到设置(在运行时)

  2. 创建一个文件,用于存储重新启动服务器时(在运行时)重新加载的这些设置

  3. 运行加载保存的设置文件的脚本(每当重新启动服务器时)

现在,如何实现:



1)首先,创建新用户时,我将在设置中创建一个新的数据库。

 从YOUR_PROJECT_NAME导入设置
database_id = user.username#只是一些独特的
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)为了方便在服务器重新启动时自动重新加载这些设置,我创建一个文件每个数据库将在服务器启动时加载。创建此文件由函数 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',#添加'postgresql_psycopg2','mysql','sqlite3'或'oracle'
'NAME':'%(NAME)如果使用sqlite3,或者数据库文件路径
'USER':'',#不与sqlite3一起使用
'PASSWORD':'',#不与sqlite3一起使用
'HOST' :'',#设置为localhost的空字符串不与sqlite3一起使用
'PORT':'',#设置为空字符串为默认值不与sqlite3一起使用
}
%db_settings
file_to_store_settings = os.path.join(path_to_store_sett ings,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 ,其中包含以下代码:

 从设置导入DATABASES 
import os

path_to_store_settings =/ path / to / your / project / YOUR_PROJECT_NAME / database_settings /
for onamelistdir(path_to_settings)中的fname:
full_path = os.path.join(path_to_settings,fname)
f = open(full_path)
content = f.read()
f.close()
exec(content)#最好确保该文件不包含任何恶意

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



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



As我说,这个工作,到目前为止我已经成功了,但这不是理想的解决方案。我真的很感激有人可以发布一个更好的解决方案。



有什么不好之处:




  • 它明确地拒绝django团队的建议,不会在运行时修改设置。我不知道为什么会提供这个建议的原因。

  • 它使用一个 exec 语句将数据加载到设置中。这应该是可以的,但是如果您在其中一个文件中收到一些损坏或恶意的代码,那么您将成为一个悲伤的熊猫。



注意我仍然使用默认数据库来查看和会话数据,但是我自己的应用程序中的所有数据都存储在用户特定的数据库中。


I've been evaluating django and wondered if the following is possible. I've already looked at the regular multiple database docs so please don't point me to that because this use case isn't mentioned as far as i can make out. If i'm wrong i take it back :)

I want one main database in which most of my app's models will reside, however one of the app's will need to dynamically create databases, these will be customer specific databases.

The database path (i plan to use sqlite) will be stored in primary database and so the cursor would need to be changed but the model will remain the same.

I would welcome any thoughts on ways to achieve this?

解决方案

I will open with "You should not edit settings at runtime".

Having said that, I have exactly this same issue, where I want to create a unique database for each user. The reason for doing this is I am offering the ability for the user to save/access to/from a database not stored on my server, which entails having multiple databases, and thus one for each user.

This answer is NOT the recommended way to achieve the desired goal. I would love to hear from a django-guru how to best approach this problem. However, this is a solution I have been using and it has worked well so far. I am using sqlite however it can be easily modified for any of the databases.

In summary, this is the process:

  1. Add the new database to settings (at runtime)
  2. Create a file to store these settings for reloading when the server is restarted (at runtime)
  3. Run a script which loads the saved settings files (whenever the server is restarted)

Now, how to achieve this:

1) Firstly, when a new user is created, I create a new database in the settings. This code lives in my view where new users are created.

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)

This script loads the database settings 'at runtime' into the django project settings. However if the server is restarted, this database will no longer be in settings.

2) To facilitate reloading these settings automatically whenever the server is restarted, I create a file for each database which will be loaded whenever the server is started. Creating this file is performed by the function 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) To actually load these settings when the server is started, I add a single line to the very bottom of /path/to/your/project/YOUR_PROJECT_NAME/settings.py, which loads each file in the settings folder and runs it, having the effect of loading the database details into the settings.

import settings_manager

Then, import settings_manager will load the file at /path/to/your/project/YOUR_PROJECT_NAME/settings_manager.py, which contains the following code:

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

Note that you could put this code directly at the bottom of settings.py instead of the import statement, but using the import statement keeps the abstraction level of settings.py consistent.

This is a convenient way to load each database setting because to remove a database from the settings all you have to do is delete the settings file, and the next time the server restarts it won't load those details into the settings, and the database will not be accessible.

As I said, this works and I have had success using it so far, but this is NOT the ideal solution. I would really appreciate if someone could post a better solution.

What's bad about it:

  • It explicitly defies advice from django team not to modify settings at runtime. I do not know the reason for why this advice is given.
  • It uses an exec statement to load the data into settings. This should be OK, but if you get some corrupt or malicious code in one of those files you will be a sad panda.

Note that I still use the default database for auth and sessions data, but all the data from my own apps is stored in the user-specific database.

这篇关于Django多个动态数据库的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆