Python | Django | バッチ処理の実装方法
公開日:2021/9/28
Pythonには,DjangoというWebアプリケーションフレームワークがある.フレームワークのため,Djangoを利用するとWebアプリを通常よりも短時間で開発することが可能になる.
2021/9/25に「OAuth認証を用いたgoogleでのログイン方法」を作成した.当該記事で実装した内容をそのまま引き継いだ上で,本記事では,「バッチ処理の実装方法」を以下4項目にて記す.
◆実施環境
Python 3.8.8
Django 3.2.3
■バッチ処理の実装方法
2021/9/25に作成した「OAuth認証を用いたgoogleでのログイン方法」で利用した"myclassbasedviewslogin"フォルダをVS Codeにて開く.その後,"myaccount"アプリに"management"フォルダを作成し,その中に"commands"フォルダを作成する."commands"フォルダに"mytest.py"を作成する.
“ec_site/myaccount/management/commands/mytest.py"を以下のように編集する.
from django.core.management.base import BaseCommand
class Command(BaseCommand):
def handle(self, *args, **options):
print('batch process 1')
VS Codeの"View"を開き,"Terminal"をクリックする.VS Codeの下部にターミナルが開くので,”conda activate 仮想環境名”を実行し,仮想環境に移行する(移行方法の詳細はこちら).ターミナルで"cd ec_site"(プロジェクト名)を入力し,ディレクトリを変更する.変更後,”python manage.py mytest”を実行する.以下が出力される.
(djangoenv) C:\Users\shiro\Desktop\210517_python development\myclassbasedviewslogin\ec_site
>python manage.py mytest
batch process 1 # 以下出力箇所
“ec_site/chem_store/management/commands/chem_store_test.py"を以下のように作成する.
“ec_site/chem_store/management/commands/chem_store_test.py"を以下のように編集する.
from django.core.management.base import BaseCommand
class Command(BaseCommand):
def handle(self, *args, **options):
print('batch process for chem_store')
ターミナルを開き,"cd ec_site"(プロジェクト名)のディレクトリで”python manage.py chem_store_test”を実行する.以下が出力される.
(djangoenv) C:\Users\shiro\Desktop\210517_python development\myclassbasedviewslogin\ec_site
>python manage.py chem_store_test
batch process for chem_store # 以下出力箇所
“ec_site/myaccount/management/commands/mytest.py"を以下のように編集する.
from django.core.management.base import BaseCommand
class Command(BaseCommand):
def add_arguments(self, parser):
parser.add_argument('name')
parser.add_argument('birthplace')
def handle(self, *args, **options):
name = options['name']
birthplace = options['birthplace']
print(f'name = {name}, birthplace = {birthplace}')
ターミナルを開き,"cd ec_site"(プロジェクト名)のディレクトリで”python manage.py mytest Jotaro Japan”を実行する.以下が出力される.
(djangoenv) C:\Users\shiro\Desktop\210517_python development\myclassbasedviewslogin\ec_site
>python manage.py mytest Jotaro Japan
name = Jotaro, birthplace = Japan # 以下出力箇所
“ec_site/myaccount/management/commands/mytest.py"を以下のように編集する.
from django.core.management.base import BaseCommand
class Command(BaseCommand):
def add_arguments(self, parser):
parser.add_argument('name')
parser.add_argument('birthplace')
parser.add_argument('--job') # 追加箇所
def handle(self, *args, **options):
name = options['name']
birthplace = options['birthplace']
job = options['job'] # 追加箇所
print(f'name = {name}, birthplace = {birthplace}, job = {job}') # 変更箇所
ターミナルを開き,"cd ec_site"(プロジェクト名)のディレクトリで”python manage.py mytest Jotaro Japan –job oceanologist”を実行する.以下が出力される.
(djangoenv) C:\Users\shiro\Desktop\210517_pythhon development\myclassbasedviewslogin\ec_sit>e>
python manage.py mytest Jotaro Japan --job oceanologist
name = Jotaro, birthplace = Japan, job = oceanologist # 以下出力箇所
“name"や"birthplace"の型を特定するため,"ec_site/myaccount/management/commands/mytest.py"を以下のように編集する.
from django.core.management.base import BaseCommand
class Command(BaseCommand):
def add_arguments(self, parser):
parser.add_argument('name', type=str) # 変更箇所
parser.add_argument('birthplace', type=str) # 変更箇所
parser.add_argument('--job')
def handle(self, *args, **options):
name = options['name']
birthplace = options['birthplace']
job = options['job']
print(type(name), type(birthplace)) # 追記箇所
print(f'name = {name}, birthplace = {birthplace}, job = {job}')
ターミナルで”python manage.py mytest Jotaro Japan –job oceanologist”を実行する.以下が出力される."name"や"birthplace"の型がどちらも"str"であることがわかる.
(djangoenv) C:\Users\shiro\Desktop\210517_python development\myclassbasedviewslogin\ec_site>python manage.py mytest Jotaro Japan --job oceanologist
<class 'str'> <class 'str'> # 以下出力箇所
name = Jotaro, birthplace = Japan, job = oceanologist
“help"によって情報を表示させるため,"ec_site/myaccount/management/commands/mytest.py"を以下のように編集する.
from django.core.management.base import BaseCommand
class Command(BaseCommand):
help='This is batch for expressing user information!'# 追加箇所
def add_arguments(self, parser):
parser.add_argument('name', type=str, help='名前を記載する') # 変更箇所
parser.add_argument('birthplace', type=str, help='出身地を記載する') # 変更箇所
parser.add_argument('--job')
def handle(self, *args, **options):
name = options['name']
birthplace = options['birthplace']
job = options['job']
print(type(name), type(birthplace))
print(f'name = {name}, birthplace = {birthplace}, job = {job}')
ターミナルで”python manage.py help mytest”を実行する.以下が出力される.
(djangoenv) C:\Users\shiro\Desktop\210517_python development\myclassbasedviewslogin\ec_site
>python manage.py help mytest
usage: manage.py mytest [-h] [--job JOB] [--version] [-v {0,1,2,3}] # 以下出力箇所
[--settings SETTINGS] [--pythonpath PYTHONPATH]
[--traceback] [--no-color] [--force-color]
[--skip-checks]
name birthplace
This is batch for expressing user information!
positional arguments:
name 名前を記載する
birthplace 出身地を記載する
optional arguments:
-h, --help show this help message and exit
--job JOB
--version show program's version number and exit
-v {0,1,2,3}, --verbosity {0,1,2,3}
Verbosity level; 0=minimal output, 1=normal
output, 2=verbose output, 3=very verbose output
--settings SETTINGS The Python path to a settings module, e.g.
"myproject.settings.main". If this isn't
provided, the DJANGO_SETTINGS_MODULE environment
variable will be used.
--pythonpath PYTHONPATH
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.
“default"により情報を表示させるため,"ec_site/myaccount/management/commands/mytest.py"を以下のように編集する.
from django.core.management.base import BaseCommand
class Command(BaseCommand):
help='This is batch for expressing user information!'
def add_arguments(self, parser):
parser.add_argument('name', type=str, help='名前を記載する')
parser.add_argument('birthplace', type=str, help='出身地を記載する')
parser.add_argument('--job', default='lawyer') # 変更箇所
def handle(self, *args, **options):
name = options['name']
birthplace = options['birthplace']
job = options['job']
print(type(name), type(birthplace))
print(f'name = {name}, birthplace = {birthplace}, job = {job}')
ターミナルで”python manage.py mytest Jotaro Japan”を実行する.以下が出力される."job"はデフォルトである"lawyer"が出力されていることがわかる.
(djangoenv) C:\Users\shiro\Desktop\210517_python development\myclassbasedviewslogin\ec_site
>python manage.py mytest Jotaro Japan
<class 'str'> <class 'str'> # 以下出力箇所
name = Jotaro, birthplace = Japan, job = lawyer
複数の単語を出力させるため,"ec_site/myaccount/management/commands/mytest.py"を以下のように編集する.
from django.core.management.base import BaseCommand
class Command(BaseCommand):
help='This is batch for expressing user information!'
def add_arguments(self, parser):
parser.add_argument('name', type=str, help='名前を記載する')
parser.add_argument('birthplace', type=str, help='出身地を記載する')
parser.add_argument('--job', default='lawyer')
parser.add_argument('five_words', nargs=5) # 追記箇所
def handle(self, *args, **options):
name = options['name']
birthplace = options['birthplace']
job = options['job']
five_words = options['five_words'] # 追記箇所
print(
f'name = {name}, birthplace = {birthplace}, job = {job}, five_words = {five_words}'
)
ターミナルで”python manage.py mytest Jotaro Japan a b c d e”を実行する.以下が出力される.
(djangoenv) C:\Users\shiro\Desktop\210517_python development\myclassbasedviewslogin\ec_site
>python manage.py mytest Jotaro Japan a b c d e
name = Jotaro, birthplace = Japan, job = lawyer, five_words = ['a', 'b', 'c', 'd', 'e'] # 以下出力箇所
“True" or “False"を出力させるため,"ec_site/myaccount/management/commands/mytest.py"を以下のように編集する.
from django.core.management.base import BaseCommand
class Command(BaseCommand):
help='This is batch for expressing user information!'
def add_arguments(self, parser):
parser.add_argument('name', type=str, help='名前を記載する')
parser.add_argument('birthplace', type=str, help='出身地を記載する')
parser.add_argument('--job', default='lawyer')
parser.add_argument('five_words', nargs=5)
parser.add_argument('--act', action='store_true') # 追記箇所
def handle(self, *args, **options):
name = options['name']
birthplace = options['birthplace']
job = options['job']
five_words = options['five_words']
act = options['act'] # 追記箇所
print(
f'name = {name}, birthplace = {birthplace}, job = {job}, five_words = {five_words}'
)
print(act) # 追記箇所
ターミナルで”python manage.py mytest Jotaro Japan a b c d e –act”を実行する.以下が出力される.
(djangoenv) C:\Users\shiro\Desktop\210517_python development\myclassbasedviewslogin\ec_site
>python manage.py mytest Jotaro Japan a b c d e --act
name = Jotaro, birthplace = Japan, job = lawyer, five_words = ['a', 'b', 'c', 'd', 'e'] # 出力箇所
True
“choose"による選択での出力をするため,"ec_site/myaccount/management/commands/mytest.py"を以下のように編集する.
from django.core.management.base import BaseCommand
class Command(BaseCommand):
help='This is batch for expressing user information!'
def add_arguments(self, parser):
parser.add_argument('name', type=str, help='名前を記載する')
parser.add_argument('birthplace', type=str, help='出身地を記載する')
parser.add_argument('--job', default='lawyer')
parser.add_argument('five_words', nargs=5)
parser.add_argument('--act', action='store_true')
parser.add_argument('--choose', choices=['Morning', 'Afternoon', 'Evening']) # 追記箇所
def handle(self, *args, **options):
name = options['name']
birthplace = options['birthplace']
job = options['job']
five_words = options['five_words']
act = options['act']
print(
f'name = {name}, birthplace = {birthplace}, job = {job}, five_words = {five_words}'
)
print(act) # 以下追記箇所
choose = options['choose']
if choose == 'Morning':
print('Good Morning')
elif choose == 'Afternoon':
print('Good Afternoon')
elif choose == 'Evening':
print('Good Evening')
ターミナルで”python manage.py mytest Jotaro Japan a b c d e –choose Evening”を実行する.以下が出力される.
(djangoenv) C:\Users\shiro\Desktop\210517_python development\myclassbasedviewslogin\ec_site
>python manage.py mytest Jotaro Japan a b c d e --choose Evening
name = Jotaro, birthplace = Japan, job = lawyer, five_words = ['a', 'b', 'c', 'd', 'e'] # 以下出力箇所
False
Good Evening
“ec_site/chem_store/management/commands"に"order_data.py"を以下のように作成する.
“ec_site/chem_store/management/commands/order_data.py"を以下のように編集する.
from django.core.management.base import BaseCommand
from chem_store.models import Orders
from ec_site.settings import BASE_DIR
from datetime import datetime
import os
import csv
class Command(BaseCommand):
def handle(self, *args, **options):
orders = Orders.objects.all()
file_path = os.path.join(BASE_DIR, 'export', 'orders', f'orders_{datetime.now().strftime("%Y%m%d%H%S")}')
with open(file_path, mode='w', newline='\n', encoding='utf-8') as csvfile:
fieldnames = ['id', 'user', 'address', 'total_price']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
for order in orders:
writer.writerow({
'id': order.id,
'user': order.user,
'address': order.address,
'total_price': order.total_price,
})
“ec_site/chem_store/management/commands/order_data.py"に"export"と"orders"を記載したので,"ec_site"に"export"フォルダを作成し,その中に"orders"フォルダを以下のように作成する.
出力されるファイルデータを事前に確認する.そのため,VS Codeにて,SQLiteをインストールし(詳細はこちら参照),"SQLITE EXPLORER"を開く.以下赤枠のorderテーブルを右クリックし,"Show Table"をクリックする.
“Show Table"の中には以下データを確認できる.
ターミナルを開き,"cd ec_site"(プロジェクト名)のディレクトリで”python manage.py order_data”を以下のように実行する.
(djangoenv) C:\Users\shiro\Desktop\210517_python development\myclassbasedviewslogin\ec_site
>python manage.py order_data
ターミナルにて上記を実行後,"ec_site/export/orders"には以下が出力される.
“ec_site/export/orders/orders_202109280101″には以下内容が記述されている.
id,user,address,total_price
1,josuke@email.com,340-0000 埼玉県 越谷市 abc street xxx,2000
2,josuke@email.com,340-0000 埼玉県 越谷市 abc street xxx,3000
3,josuke@email.com,340-0000 埼玉県 越谷市 abc street xxx,3000
ユーザーごとにファイルを出力させるため,"ec_site/chem_store/management/commands/order_data.py"に追記し,以下のように編集する.
from django.core.management.base import BaseCommand
from chem_store.models import Orders
from ec_site.settings import BASE_DIR
from datetime import datetime
import os
import csv
class Command(BaseCommand):
def add_arguments(self, parser): # 追記箇所(以下2行)
parser.add_argument('--user_id', default='all')
def handle(self, *args, **options):
orders = Orders.objects.all()
user_id = options['user_id'] # 追記箇所(以下5行)
if user_id == 'all':
orders = orders.all()
else:
orders = orders.filter(user_id=user_id)
file_path = os.path.join(BASE_DIR, 'export', 'orders', f'orders_{datetime.now().strftime("%Y%m%d%H%M%S")}') # 変更箇所("%M"追記)
with open(file_path, mode='w', newline='\n', encoding='utf-8') as csvfile:
fieldnames = ['id', 'user', 'address', 'total_price']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
for order in orders:
writer.writerow({
'id': order.id,
'user': order.user,
'address': order.address,
'total_price': order.total_price,
})
ターミナルを開き,”python manage.py order_data –user_id 1”を以下のように実行する.
(djangoenv) C:\Users\shiro\Desktop\210517_python development\myclassbasedviewslogin\ec_site
>python manage.py order_data --user_id 1
“ec_site/export/orders"に以下のようにファイルが出力される.
“ec_site/export/orders/orders_20210928022748″には以下データが出力されている.user_idが1のオーダー情報はないので,以下データの出力となる.
id,user,address,total_price
ターミナルを開き,”python manage.py order_data –user_id 2”を以下のように実行する.
(djangoenv) C:\Users\shiro\Desktop\210517_python development\myclassbasedviewslogin\ec_site
>python manage.py order_data --user_id 2
“ec_site/export/orders"に以下のようにファイルが出力される.
“ec_site/export/orders/orders_20210928022852″には以下データが出力されている.user_idが2のオーダー情報は以下データの出力となる.
id,user,address,total_price
1,josuke@email.com,340-0000 埼玉県 越谷市 abc street xxx,2000
2,josuke@email.com,340-0000 埼玉県 越谷市 abc street xxx,3000
3,josuke@email.com,340-0000 埼玉県 越谷市 abc street xxx,3000
https://docs.djangoproject.com/ja/3.1/howto/custom-management-commands/
以上