预定的,带时间戳的sqlite3 .backup?

时间:2017-02-02 08:39:39

标签: django sqlite pythonanywhere

在pythonanywhere上运行一个小数据库,我正在尝试设置我的sqlite3数据库的预定.backup。在命令行中是否有任何方法可以为文件名添加时间/日期戳,以便它不会覆盖前几天的备份?

以下是我正在使用的代码,如果重要的话:

sqlite3 db.sqlite3
.backup dbbackup.sqlite3
.quit

每24小时运行一次。但是,前一天的备份被覆盖了。我希望能够将其保存为dbbackup.timestamp.sqlite3或其他东西,所以我可以提供多个备份。

谢谢!

1 个答案:

答案 0 :(得分:0)

  

我建议您使用management commands和cronjob处理此案例。

这个例子怎么做;保存此文件,例如yourapp/management/commands/dbackup.py,请不要忘记添加__init__.py个文件。

yourapp/management/__init__.py
yourapp/management/commands/__init__.py
yourapp/management/commands/dbackup.py

但是,之前将这些行添加到您的settings.py

USERNAME_SUPERUSER = 'yourname`
PASSWORD_SUPERUSER = `yourpassword`
EMAIL_SUPERUSER = `youremail@domain.com`
DATABASE_NAME = 'db.sqlite3'

如果在pythonanywhere部署,那么重要的树路径项目;

/home/yourusername/yourproject/manage.py
/home/yourusername/yourproject/db.sqlite3
/home/yourusername/yourproject/yourproject/settings.py
/home/yourusername/yourproject/yourapp/management/commands/dbackup.py

将以下这些脚本添加到yourapp/management/commands/dbackup.py中,您也可以根据需要自定义此脚本。

import os
import time
from django.conf import settings
from django.contrib.auth.models import User
from django.core.management.base import (BaseCommand, CommandError)

USERNAME_SUPERUSER = settings.USERNAME_SUPERUSER
PASSWORD_SUPERUSER = settings.PASSWORD_SUPERUSER
EMAIL_SUPERUSER = settings.EMAIL_SUPERUSER
DATABASE_NAME = settings.DATABASE_NAME #eg: 'db.sqlite3'


class Command(BaseCommand):
    help = ('Command to deploy and backup the latest database.')

    def add_arguments(self, parser):
        parser.add_argument(
            '-b', '--backup', action='store_true',
            help='Just backup command confirmation.'
        )

    def success_info(self, info):
        return self.stdout.write(self.style.SUCCESS(info))

    def error_info(self, info):
        return self.stdout.write(self.style.ERROR(info))

    def handle(self, *args, **options):
        backup = options['backup']

        if backup == False:
            return self.print_help()

        # Removing media files, if you need to remove all media files
        # os.system('rm -rf media/images/')
        # self.success_info("[+] Removed media files at `media/images/`")

        # Removing database `db.sqlite3`
        if os.path.isfile(DATABASE_NAME):
            # backup the latest database, eg to: `db.2017-02-03.sqlite3`
            backup_database = 'db.%s.sqlite3' % time.strftime('%Y-%m-%d')
            os.rename(DATABASE_NAME, backup_database)
            self.success_info("[+] Backup the database `%s` to %s" % (DATABASE_NAME, backup_database))

            # remove the latest database
            os.remove(DATABASE_NAME)
            self.success_info("[+] Removed %s" % DATABASE_NAME)

        # Removing all files migrations for `yourapp`
        def remove_migrations(path):
            exclude_files = ['__init__.py', '.gitignore']
            path = os.path.join(settings.BASE_DIR, path)

            filelist = [
                f for f in os.listdir(path)
                if f.endswith('.py')
                and f not in exclude_files
            ]
            for f in filelist:
                os.remove(path + f)
            self.success_info('[+] Removed files migrations for {}'.format(path))

        # do remove all files migrations
        remove_migrations('yourapp/migrations/')

        # Removing all `.pyc` files
        os.system('find . -name *.pyc -delete')
        self.success_info('[+] Removed all *.pyc files.')

        # Creating database migrations
        # These commands should re-generate the new database, eg: `db.sqlite3`
        os.system('python manage.py makemigrations')
        os.system('python manage.py migrate')
        self.success_info('[+] Created database migrations.')

        # Creating a superuser
        user = User.objects.create_superuser(
            username=USERNAME_SUPERUSER,
            password=PASSWORD_SUPERUSER,
            email=EMAIL_SUPERUSER
        )
        user.save()
        self.success_info('[+] Created a superuser for `{}`'.format(USERNAME_SUPERUSER))

使用crontab

设置此命令
$ sudo crontab -e

并在下面的行中添加以下内容;

# [minute] [hour] [date] [month] [year]
59 23 * * * source ~/path/to/yourenv/bin/activate && cd ~/path/to/yourenv/yourproject/ && ./manage.py dbackup -b

但是,如果你需要在pythonanywhere部署,你只需要添加这些..

每日[hour][minute] UTC,...填写hour=23minute=59

source /home/yourusername/.virtualenvs/yourenv/bin/activate && cd /home/yourusername/yourproject/ && ./manage.py dbackup -b

更新1

  

我建议您更新执行manage.py文件的命令,例如os.system('python manage.py makemigrations'),其功能为call_command;

from django.core.management import call_command
call_command('collectstatic', verbosity=3, interactive=False)
call_command('migrate', 'myapp', verbosity=3, interactive=False)

...等于在终端中输入的以下命令:

$ ./manage.py collectstatic --noinput -v 3
$ ./manage.py migrate myapp --noinput -v 3

请参阅running management commands from django docs

更新2

以前的情况是您需要重新部署项目并使用新数据库。 ,如果您只想通过重命名数据库进行备份,则可以使用shutil.copyfile模块

import os
import time
import shutil
from django.conf import settings
from django.core.management.base import (BaseCommand, CommandError)

DATABASE_NAME = settings.DATABASE_NAME #eg: 'db.sqlite3'


class Command(BaseCommand):
    help = ('Command to deploy and backup the latest database.')

    def add_arguments(self, parser):
        parser.add_argument(
            '-b', '--backup', action='store_true',
            help='Just backup command confirmation.'
        )

    def success_info(self, info):
        return self.stdout.write(self.style.SUCCESS(info))

    def error_info(self, info):
        return self.stdout.write(self.style.ERROR(info))

    def handle(self, *args, **options):
        backup = options['backup']

        if backup == False:
            return self.print_help()

        if os.path.isfile(DATABASE_NAME):
            # backup the latest database, eg to: `db.2017-02-29.sqlite3`
            backup_database = 'db.%s.sqlite3' % time.strftime('%Y-%m-%d')
            shutil.copyfile(DATABASE_NAME, backup_database)
            self.success_info("[+] Backup the database `%s` to %s" % (DATABASE_NAME, backup_database))