首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Django:在运行时对动态数据库连接编程使用'inspectdb‘

Django:在运行时对动态数据库连接编程使用'inspectdb‘
EN

Stack Overflow用户
提问于 2019-07-25 15:09:57
回答 1查看 269关注 0票数 2

我有一个Django项目,其中每个用户组都有自己的数据库(“项目”)。每个项目都有一个条目,保存在主数据库中。从主数据库中,Django读取所有当前项目,并与其数据库建立连接。这就是为什么连接不是用settings.py编写的。动态连接到项目数据库的代码片段在根urls.py中运行,因为我从stackoverflow上的另一个线程了解到,那里的代码在启动时运行一次。每当用户创建新项目时,一段代码都会创建一个新数据库,并通过附加到settings.DATABASES的连接来连接到新数据库(请参阅下面的示例代码)。一个外部程序被触发,用数据填充新数据库。

现在的问题是我不能立即使用数据库,因为首先我需要运行inspectdb来获取Django的ORM结构。我希望在运行时这样做,因为必须关闭服务器并重新启动它将意味着其他用户在此期间无法使用他们的项目。但即使手动使用命令行,Django也会返回连接不存在的错误。(我猜它试图在settings.py中找到连接?)。但是,对于我已经创建了ORM结构的项目,可以找到连接。因此,我认为问题不在于将连接附加到settings.DATABASES的代码片段。

我试着用下面的方法解决上述问题

代码语言:javascript
复制
command = 'python manage.py inspectdb --database ' + name + ' > api_manager/schemas/' + name + '.py'
    os.system(command)

但是,如上所述,它会引发连接不存在的异常。

在settings.py中,仅存在默认数据库:

代码语言:javascript
复制
DATABASES = {
    'default': {
        'ENGINE': engine,
        'NAME': name,
        'USER': user,
        'PASSWORD': pwd,
        'HOST': host,
        'PORT': port
    }
}

在根urls.py中:

代码语言:javascript
复制
...
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()代码:

代码语言:javascript
复制
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)

项目创建:

代码语言:javascript
复制
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

在外部程序运行后运行的一段代码:

代码语言:javascript
复制
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,仍然没有成功。

EN

回答 1

Stack Overflow用户

发布于 2020-01-17 17:48:27

我通过rest调用运行此代码:

代码语言:javascript
复制
from django.core.management import call_command
# base dir from your's project settings
from project_name.settings import BASE_DIR
import os 

with open(os.path.join(BASE_DIR, 'inspected.py'), 'w+') as f
    call_command("inspectdb", stdout=f)

manage.py附近的...and接收结果文件。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57196193

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档