【发布时间】:2019-12-03 09:23:12
【问题描述】:
我有一个 Django 项目,其中每个用户组都有自己的数据库(“项目”)。每个项目都有一个条目,它保存在主数据库中。 Django 从主数据库读取所有当前项目并连接到他们的数据库。这就是为什么连接没有写在 settings.py 中的原因。动态连接到项目数据库的代码在根 urls.py 中运行,因为我从 stackoverflow 上的另一个线程中了解到,那里的代码在启动时运行一次。每当用户创建一个新项目时,一段代码都会创建一个新数据库并通过将连接附加到 settings.DATABASES 来连接到新数据库(参见下面的示例代码)。 触发了一个外部程序来用数据填充新数据库。
现在的问题是我不能立即使用数据库,因为首先我需要运行 inspectdb 来获取 Django 的 ORM 结构。 我想在运行时执行此操作,因为必须关闭服务器并重新启动它意味着其他用户在此期间无法使用他们的项目。但即使手动使用命令行,Django 也会回答连接不存在的错误。 (我猜它试图在 settings.py 中找到连接?)。但是对于我已经创建了 ORM 结构的项目,可以找到连接。所以我认为问题不在于将连接附加到 settings.DATABASES 的那段代码。
我尝试使用
解决上述问题command = 'python manage.py inspectdb --database ' + name + ' > api_manager/schemas/' + name + '.py'
os.system(command)
但是,如上所述,它会引发连接不存在的异常。
在 settings.py 中只存在默认数据库:
DATABASES = {
'default': {
'ENGINE': engine,
'NAME': name,
'USER': user,
'PASSWORD': pwd,
'HOST': host,
'PORT': port
}
}
在根 urls.py 中:
...
from myproject.utils import connect_to_db
urlpatterns = [
...
]
# one time execution
for project in Project.objects.all():
connect_to_db(project.slug)
connect_to_db() 代码:
def connect_to_db(project):
settings.DATABASES[project] = {
'ENGINE': settings.engine,
'NAME': project,
'USER': settings.user,
'PASSWORD': settings.pwd,
'HOST': settings.host,
'PORT': settings.port
}
print("CONNECTED TO DATABASE: " + project)
项目创建:
def create_new_project(project_name):
slug = slugify(project_name).replace('-', '')
project_dir = os.path.join(settings.MEDIA_ROOT, "projects", slug)
try:
# Create entry in default database
project = Project()
project.name = project_name
project.slug = slug
project.save()
# Create new database
with connection.cursor() as cursor:
cursor.execute("CREATE DATABASE " + slug)
# Create projects folder in media
if not os.path.exists(project_dir):
os.mkdir(project_dir)
# create some other folders
else:
raise Exception("Project folder already exists!")
connect_to_db(slug)
return project
except:
raise
外部程序运行后运行的一段代码:
command = 'python manage.py inspectdb --database ' + name + ' > myapp/schemas/' + name + '.py'
os.system(command) # raises exception connection 'name' doesn't exist
我希望 Django 在运行时创建一个新的 ORM (models.py) 文件,以便我的用户可以立即使用新生成的数据库。
编辑:我用 subprocess.run(...) 而不是 os.system 尝试了同样的事情,但仍然没有成功。
【问题讨论】: