読者です 読者をやめる 読者になる 読者になる

Django のダミーデータを大量投入するスクリプトを対話環境に対応させるシェルスクリプトで自動化した

python Django sh

やっぱりだるかった

Django アプリのダミーデータを大量投入するスクリプトをかく - AtAsAtAmAtArAのをコピペ運用でもよかったけど、コピペ条件かわったりいちいちもうそういうのだるかったので、やっぱりデータを初期化するところまで自動化することにした。

expect をつかった

Django ORM から生成したいからスクリプトは変えたくない。でも余計な python ライブラリは気持ち的にあまりいれたくない。python manage.py sql... とかいろいろあるけど、どうもつかえなさそうだ。python manage.py shell は python -c みたいに直接実行ができない。対話シェルになるのは必然っぽい。じゃあどうしよう。

対話シェルになってしまうものをむりやりどうにかできないか探したらあっさり expect というのが見つかった。パターンマッチさせてコマンドを実行させてしまう。すごい。sshrsync とか useradd とかで使うのを想定しているみたいだけど、これはいけそうだ。

sudo apt-get install expect

参考::clmemo@aka: Expect コマンドで passwd 変更
参考::Linux なら expect でコマンドを自動化しよう | 温故知新 linux実践講座

パターンマッチは --plain でやった

python にも pexpect なるパッケージもあるけど、あんまり今回はいれたくなかったのでどうにかシェルスクリプトでやりたい。python manage.py shell だとどうしても ipython か bpython が選択されてしまう。そのとき "In [1]: "のマッチでよくわからないがコケる。こまった。

結局 python manage.py shell は --plain で ipython とか使わないプレーンな標準の対話シェルが指定できるから、それをやった。

成果

だいぶゴリ押し感ある

#!/bin/bash

current_dir = ...
target_dir = ...

cp $current_dir/make_dummy_data.py $terget_dir
rm ...
python manage.py syncdb ...
python manage.py migrate ...

expect -c "
set timeout 1

expect '>>>'
send "import make_dummy_data\n"

expect '>>>'
send "make_dummy_data.main()\n"

expect '>>>'
send "exit()\n"

interactive
"

send したら改行コードを忘れずに。エスケープはてきとう。 set timeout でタイムアウト指定できるから -1 とかにもしたけど、なんかだめっぽかったからてきとうに小さい値を入れておいた。

まあ

よかったんだが、実は echo でよかったらしい

echo "print(1)" | python manage.py shell

なにをやっていたのだか……