はじめに
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はもちろん任意の名前で)
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