django 生产环境使用了错误的数据库

django production environment is using the wrong db

我正在写我的第一个 'self-made deployment'。使用 fabric 编写部署脚本。我在我的生产机器上添加了一个导出到 .bashrc 以导出一个 key:value {'DIGITAL_OCEAN': True} 所以我可以在我的设置中添加一些条件来使用基于本地或生产环境的数据库。

SETTINGS.PY

import os
if 'DIGITAL_OCEAN' in os.environ:
        ON_DO = True
else:
        ON_DO = False

if ON_DO:
        DATABASES = {
        'default': {
                'ENGINE': 'django.db.backends.postgresql_psycopg2',
                'NAME': 'user',
                'USER': 'user',
                'PASSWORD': 'pass',
                'HOST': 'localhost',
                'PORT': '',
                }
        }
else:
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.postgresql_psycopg2',
            'NAME': 'localuser',
            'USER': 'localuser',
            'PASSWORD': 'localpass',
            'HOST': 'localhost',
            'PORT': '',
            }

现在...如果我 运行 像 '$ python manage.py migrate' 这样的 ssh 命令一切顺利 ON_DO 被发现并且一切顺利,但是在下面列出的我的部署脚本中,ON_DO 显示为 false,我之前自发发生过这种情况,然后它自行纠正(可能通过 gunicorn 或 nginx 重启)所以我尝试向脚本添加一些重启,但没有到目前为止运气不错,我没有想法。

def server():

        '''IDK'''
        env.host_string = 'ip.ip.ip.ip'
        env.user = 'root'

def pull_deploy():

        '''Makes the server pull it from git repo at bitbucket'''

        path = '/home/django/'


        print(red('BEGINNING PULL DEPLOY'))

        with cd('%s' % path) :
                run('pwd')
                print(green('Pulling Master from Bitbucket'))
                run('git pull origin master')

                print(green('SKIPPING installing requirements'))
                run('source %spyenv/bin/activate && pip install -r langalang/requirements.txt' % path)

                print('Collecting static files')
                run('source %spyenv/bin/activate && python langalang/manage.py collectstatic' % path)

                print('Restarting Gunicorn')
                run('sudo service gunicorn restart')
                print('Restarting Nginx')
                run('nginx -s reload')

                print('Making migrations')
                run('source %spyenv/bin/activate && python langalang/manage.py makemigrations' % path)

                print('Migrating DB')
                run('source %spyenv/bin/activate && python langalang/manage.py migrate' % path)

                print('Restarting Gunicorn')
                run('sudo service gunicorn restart')
                print('Restarting Nginx')
                run('nginx -s reload')
                print(red('DONE'))

问题是我在 ~.bashrc 或 ~.profile 中声明了我的环境变量 'ON_DO',而那些只从登录 shell 导出变量。我猜 django 在它自己运行时不算作登录 shell。我不得不从 django 本身的 .wsgi 文件中导出它们。

据我所知,该文件仅在生产环境中运行,因此它仅将变量输出到生产系统。

@deltaskelta 为什么要在 wsgi.py 文件中设置变量?它不会破坏目的,因为这个变量也将在您的开发环境中设置。

这是我写的 shell 脚本。

#!/bin/sh

ps aux | grep usr/bin/[p]ython

if [ $? != 0 ]
then
    export UNIQUE_KEY='value'
    python ~/project_name/manage.py runserver 0:8000
    exit 0
else
    exit 1
fi

它的作用是,在它执行时设置 UNIQUE_KEY 环境变量,并在它停止时立即取消设置。 此外,它也适用于 crontab 这是有效的,因为通过 crontab 执行的 shell 脚本是 运行 在 non-interactive non-login shell session 中。

深入了解不同的 shell 会话可能会有所帮助。

The Difference between Login, Non-Login, Interactive, and Non-Interactive Shell Sessions

The bash shell reads different configuration files depending on how the session is started.

One distinction between different sessions is whether the shell is being spawned as a "login" or "non-login" session.

A login shell is a shell session that begins by authenticating the user. If you are signing into a terminal session or through SSH and authenticate, your shell session will be set as a "login" shell.

If you start a new shell session from within your authenticated session, like we did by calling the bash command from the terminal, a non-login shell session is started. You were were not asked for your authentication details when you started your child shell.

Another distinction that can be made is whether a shell session is interactive, or non-interactive.

An interactive shell session is a shell session that is attached to a terminal. A non-interactive shell session is one is not attached to a terminal session.

Check this link for details - Digital Ocean Tutorials