1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Djangoのバッチをつくってcronで日次実行する

Last updated at Posted at 2023-01-18

はじめに

vietnam_research には、バッチ処理があった。

最近このアプリケーションをナマSQLベースからQuerySetベースに変えるリファクタリングを行っていた。そしたらこんなエラーが出るようになった。

こんなエラー
RuntimeError: Model class mysite.vietnam_research.models.Market 
doesn't declare an explicit app_label and isn't in an application 
in INSTALLED_APPS.

訳:
RuntimeError: モデルクラス mysite.vietnam_research.models.Market
は、明示的な app_label を宣言しておらず、INSTALLED_APPS の
アプリケーションに含まれていません。

しばらく原因がわからなかったんだけど、どうやら「Modelを使うならDjangoドメイン(=ディレクトリの中)でつくれよ」っていう話らしい。そうかー、生SQLだから気が付かなかったのか

参考

手順

バッチファイル新規作成

vietnam_research アプリケーション配下に management/commands/daily_chart.py ファイルを新規追加します(※daily_chartはもちろん任意の名前で)
image.png

mysite/vietnam_research/management/commands/daily_chart.py
from django.core.management.base import BaseCommand, CommandError
from vietnam_research.models import Industry


class Command(BaseCommand):
    help = 'plot industry stacked bar_chart'

    def add_arguments(self, parser):
        parser.add_argument('industry_ids', nargs='+', type=int)

    def handle(self, *args, **options):
        for industry_id in options['industry_ids']:
            try:
                industry = Industry.objects.get(pk=industry_id)
            except Industry.DoesNotExist:
                raise CommandError('Industry "%s" does not exist' % industry_id)

            industry.open_price = 99.9
            industry.save()

            self.stdout.write(self.style.SUCCESS('Successfully updated industry "%s"' % industry_id))

確認

  • plot industry stacked bar_chart という文字が確認できたということは daily_chart がバッチコマンドとして認識されたということだ

バッチコマンドが認識されたことを確認

console
dev\portfolio\mysite> python manage.py daily_chart -h
usage: manage.py daily_chart [-h] [--version] [-v {0,1,2,3}] [--settings SETTINGS] [--pythonpath PYTHONPATH] [--traceback] [--no-color] [--force-color] [--skip-checks] industry_ids [industry_ids ...]

plot industry stacked bar_chart

positional arguments:
                        A directory to add to the Python path, e.g. "/home/djangoprojects/myproject".
  --traceback           Raise on CommandError exceptions.
  --no-color            Don't colorize the command output.
  --force-color         Force colorization of the command output.
  --skip-checks         Skip system checks.

更新前の確認

console
dev\portfolio> python manage.py shell
shell
# Industry テーブルの1レコードめの open_price の確認
In [1]: from vietnam_research.models import Industry
In [2]: query = Industry.objects.get(pk=1)
In [3]: query.open_price
Out[3]: Decimal('12.40')
In [4]: exit

バッチ実行

  • スペース区切りにすると list で送ったことになるらしい(loop処理される)
console
dev\portfolio\mysite> python manage.py daily_chart 1 2
Successfully updated industry "1"
Successfully updated industry "2"

更新前の確認

console
dev\portfolio> python manage.py shell
shell
# Industry テーブルの1レコードめの open_price の確認
In [1]: from vietnam_research.models import Industry
In [2]: query = Industry.objects.get(pk=1)
In [3]: query.open_price
Out[3]: Decimal('99.90')
In [4]: exit

cronでセット

console(ubuntu)
# cp /etc/crontab /etc/cron.d/cron_for_portfolio
# vi /etc/cron.d/cron_for_portfolio
/home/ubuntu/etc/cron.d/cron_for_portfolio
51  *  *  *  * /var/www/html/venv/bin/python /var/www/html/portfolio/mysite/manage.py daily_chart
console(ubuntu)
# service cron restart
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?