外部のに対しては、EP.03 で扱ったように相手への配慮を考えます。ところが社内のデータベースが相手になると、途端に遠慮が消えます。自社のデータだから、という感覚があるからです。
しかし実態は逆で、社内のほうが影響が直接的です。外部のサービスなら遮断されて終わりですが、社内の本番データベースを重い問い合わせで詰まらせると、業務そのものが止まります。注文が通らない、画面が開かない、という形で表に出ます。
この回では、社内のデータを取るときに何に気をつけるかを扱います。技術というより、運用上の作法の話が中心になります。
本番に直接向けない
最初に検討すべきは、が用意されていないかです。読み取り専用の複製先があれば、そこへ向けるだけで本番への影響がなくなります。多くの環境では既に用意されているので、まず聞いてみる価値があります。
複製先には反映の遅れがあります。数秒から数分ほど古い状態を見ることになるので、最新の値が必須の用途には向きません。分析用途なら、この遅れが問題になることはまずありません。
設定ファイルに本番と複製先の両方を書いておくと、うっかり本番を指したまま実行する事故が起きます。分析用の処理からは、そもそも本番の接続情報を読めないようにしておくのが確実です。
重い問い合わせを避ける
の書き方でも負荷は大きく変わります。とくに効くのが、取る範囲を絞ることと、必要な列だけを選ぶことの2つです。どちらも当たり前に聞こえますが、探索的に触っているとつい全件を取ってしまいます。
全期間を1回で取ろうとせず、期間で分けて何度かに分けるのも有効です。1回あたりの負荷が下がり、途中で失敗しても EP.07 の要領で続きから再開できます。
from datetime import date, timedelta
def month_ranges(start: date, end: date): """月ごとの (開始, 終了) を返す。1 回の問い合わせを月単位に抑える。""" cur = start.replace(day=1) while cur <= end: nxt = (cur + timedelta(days=32)).replace(day=1) yield max(cur, start), min(nxt - timedelta(days=1), end) cur = nxt
def fetch_by_month(conn, start: date, end: date): sql = """ SELECT id, created_at, amount FROM orders WHERE created_at >= %(from)s AND created_at < %(to)s """ for a, b in month_ranges(start, end): # パラメータで渡す。文字列を組み立てて埋め込まない yield a, conn.execute(sql, {"from": a, "to": b + timedelta(days=1)})上のコードで値をパラメータとして渡しているのは、文字列を組み立てて埋め込むと注入の余地ができるからです。社内のデータで、入力も自分が書いた日付だとしても、この書き方を習慣にしておく価値があります。
接続先を間違えない仕掛け
「本番に向けない」と決めても、設定を間違えれば向いてしまいます。人の注意力に頼らず、間違った接続先では動かない仕掛けを入れておくのが確実です。接続した直後に、そこが読み取り専用かどうかを確かめます。
取得した結果はに置き、EP.12 の要領で日付ごとにしておくと、後から範囲を絞って読めます。社内データでも、取り直しに時間がかかる点は外部と変わりません。
def assert_read_only(conn) -> None: """書き込める接続なら、その場で止める。 設定ミスで本番へ向いていた場合、ここで気づける。""" try: conn.execute("CREATE TEMP TABLE _probe (x int)") except Exception: return # 書けない = 読み取り専用。想定どおり
conn.execute("DROP TABLE IF EXISTS _probe") raise RuntimeError( "書き込み可能な接続になっている。分析用の接続先を確認すること" )いつ実行するかを決める
同じ問い合わせでも、実行する時間帯で影響が変わります。業務のピーク時間を避けるだけで、多くの問題は起きなくなります。夜間や早朝に回すのが基本です。
月末や期末のように、業務側が重くなる時期も避けてください。定期実行に載せる場合、その日だけ止める仕組みがあると安心です。止め方が無いと、忙しい時期に手で無効化することになります。
| 確認 | なぜ |
|---|---|
| 読み取り専用の複製先があるか | 本番への影響を消せる |
| 接続に使う権限は読み取りだけか | 誤って書き換える余地を無くす |
| 実行する時間帯 | 業務のピークを避ける |
| 1回あたりの所要時間 | 長いほど詰まりやすい |
| 止め方が用意されているか | 忙しい時期に手で止められる |
権限は読み取りだけに絞ってください。分析のための取得に書き込みは要りません。権限があると、いつか事故が起きます。データ基盤側の権限設計については 壊れないデータ基盤の作り方 で扱っています。次回は、もっと素朴な経路を扱います。
社内のデータだからこそ、影響が出たときに困る人の顔が見えます。外部の相手より配慮すべき、と考えておくくらいでちょうどよいと思います。
この記事の感想を教えてください
あなたの 1 クリックで、本当にこの記事は更新されます。「もっと詳しく」「続編希望」が一定数集まった記事は、 ふくふくが 実際に内容を拡充したり続編記事を公開 します。 送信したリアクションはお使いのブラウザに記録され、再カウントされません。