在 django 中,如何从初始化脚本中调用子命令“syncdb”?
Posted
技术标签:
【中文标题】在 django 中,如何从初始化脚本中调用子命令“syncdb”?【英文标题】:In django, how do I call the subcommand 'syncdb' from the initialization script? 【发布时间】:2011-03-30 14:03:44 【问题描述】:我是 python 和 django 的新手,在关注 Django Book 时,我了解了为我生成数据库表的命令“python manage.py syncdb”。在开发环境中,我在内存数据库中使用 sqlite,所以每次我重新启动服务器时它都会自动删除。那么如何编写这个“syncdb”命令的脚本呢?(应该在“settings.py”文件中完成吗?)
澄清
OP 正在使用内存数据库,该数据库需要在使用针对该数据库定义的 Django 模型的任何进程开始时进行初始化。确保数据库初始化(每个进程启动一次)的最佳方法是什么。这将用于通过manage.py runserver
或通过网络服务器进程(例如使用 WSGI 或 mod_python)运行测试或运行服务器。
【问题讨论】:
【参考方案1】:所有 Django 管理命令can be accessed programmatically:
from django.core.management import call_command
call_command('syncdb', interactive=True)
理想情况下,您应该在 runserver
上使用预初始化信号来激活它,但这样的信号 doesn't exist。所以,实际上,如果我是你,我的处理方式是创建一个自定义管理命令,如 runserver_newdb
,并在其中执行:
from django.core.management import call_command
call_command('syncdb', interactive=True)
call_command('runserver')
有关编写自定义管理命令的更多信息,请参阅the documentation。
【讨论】:
您会将“from django.core.management import call_command call_command('syncdb', interactive=True)”放在哪个文件中(在典型的 django 项目中)? @EdwardD'Souza:对于这个用例,我会将其放入settings.py
或从settings.py
导入的脚本中【参考方案2】:
正如“Where to put Django startup code?”所建议的,您可以将中间件用于您的启动代码。 Django 文档是here。
例如(未经测试):
startup.py:
from django.core.exceptions import MiddlewareNotUsed
from django.conf import settings
from django.core.management import call_command
class StartupMiddleware(object):
def __init__(self):
# The following db settings name is django 1.2. django < 1.2 will use settings.DATABASE_NAME
if settings.DATABASES['default']['NAME'] == ':memory:':
call_command('syncdb', interactive=False)
raise MiddlewareNotUsed('Startup complete')
在你的 settings.py 中:
MIDDLEWARE_CLASSES = (
'your_project.middleware.startup.StartupMiddleware',
# Existing middleware classes here
)
【讨论】:
【参考方案3】:更新
我在项目的根目录中添加了一个名为run.sh
的脚本。这适用于我的 SQLite 数据库:
#!/usr/bin/python
from django.core.management import call_command
call_command('syncdb')
call_command('runserver')
原答案
我不确定我是否理解您所说的“编写 syncdb 命令脚本”是什么意思。您通常从命令行执行python manage.py syncdb
。这通常在添加新模型后完成。如果您希望使用简单的 shell 脚本轻松完成此操作。我看不出有任何理由在 settings.py
中放置(或调用)syncdb
。
您能否为您的问题添加更多详细信息?添加上下文并解释您到底想要完成什么?
【讨论】:
我希望像任何其他python方法一样调用这个'syncdb'命令,并将调用放在settings.py中,所以每次我启动应用程序时它都会自动创建数据库 知道了。我不相信settings.py
是保存它的最佳位置。我们可以同意不同意:)
您还有什么建议吗?我对python完全陌生。正如 Craig Trader 所说,“syncdb”的调用必须发生在同一个进程中,所以我想这让 shell 脚本毫无疑问。
找到了通过API调用syncdb
的机制。更新了答案。关于放置它的位置还没有更好的想法:(
自从丹尼尔回答了第一个学分归他所有,但无论如何 +1 为您的帮助,谢谢。【参考方案4】:
您可以创建一个您调用的新脚本,而不是调用 manage.py 的 manage.py:
from subprocess import call
call(["python", "manage.py", "syncdb"])
call(["python", "manage.py", "runserver"])
如果您不需要添加管理员,您可以像这样更改第二行:
call(["python", "manage.py", "syncdb", "--noinput"])
我假设您要做的是创建您的数据库,然后每次使用一个命令启动您的服务器。
【讨论】:
我希望以某种 python API 的形式访问“syncdb”,但没关系。 这可能不适用于内存数据库,因为每个call
都在调用一个单独的进程,该进程将拥有自己的内存数据库。
是的,你是对的。这可能会让 bash 脚本毫无疑问。【参考方案5】:
@Daniel Naab 的回答,以及官方网站中的文档,不是用于执行管理命令作为入口点。
如果您想在 AWS Lambda 或 Google Cloud Functions 等托管云环境中使用管理命令作为入口点,您可以查看 manage.py
并尝试类似的方法。
import os
from django.core.management import execute_from_command_line
def publishing_fn(data, context):
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'YOURAPP.settings')
# The first argument is "manage.py" when it's run from CLI.
# It can be an empty string in this case
execute_from_command_line(['', 'COMMAND', 'ARGS...'])
【讨论】:
以上是关于在 django 中,如何从初始化脚本中调用子命令“syncdb”?的主要内容,如果未能解决你的问题,请参考以下文章