はじめに
みなさん、こんにちは。5月も半ばに差し掛かりました。
本社がある札幌でも、桜が散りチューリップなど、新緑を感じられる季節になってきました!
さて、前回まではDjangoとSQLiteの二つを使用して、データベースを作ってきました。これにより、マウスやキーボードの操作によって、管理画面からデータベースにゴミを登録することができるようになりました!
まだご覧になられてない方、ぜひご覧ください!
今回の内容
データをまとめて登録したい・・・
今回は、前回手動入力でできた地域名やゴミの情報の登録を、一括登録していきいます。
前回は一つ一つデータを手で入力していました。ですが、これでは47都道府県を入力するだけでも、たくさんの時間と労力がかかってしまいます。そこで、これが一括登録できるようになると手間がかからなくて素敵ですよね。今日はそれができるようにチャレンジしてみたいと思います!
今回使用する技術
今回はCSVファイル作り、それをPythonでDjangoに読み込ませてSQLiteへデータベースを作っていきます。
CSVファイルは、簡単に説明すると表のファイルです。ExcelやGoogleスプレッドシートで視覚的に編集して作成する方法や、VS Codeなどのエディタで書く方法などがあります。いままでの私だったら、Excelを好んで使っていたと思いますが、今回はせっかくなのでCursorを使って制作することにしましょう!
データベースに読み込ませる準備
今回作っていくのは、3つのCSVファイルに加えて、管理コマンドを作っていきます。
それぞれ作るファイルは以下のディレクトリ構成を参考に作ってみてください!
garbage/
├── management/
│ └── commands/
│ └── import_data.py ← 管理コマンド
├── migrations/
├── models.py
├── ...
cities.csv
garbage_categories.csv
city_category_names.csv
CSVファイル
まずは読み込ませていくCSVファイルを作っていきます。
今回作っていくCSVファイルは、前回作成した3つのゴミのカテゴリー分作るので、3つ作ります。3つのファイルは、上のディレクトリ構成を参考にしながら、作ってみてください!
cities.csvには都市の名前を入れていきます。今回は、大都市圏及び都市圏である以下の17地域をピックアップしてみました。nameの下に一行ずつ都市の名前を書いていきましょう!
name
札幌市
仙台市
千葉市
横浜市
川崎市
名古屋市
大阪市
神戸市
京都市
広島市
福岡市
北九州市
新潟市
浜松市
岡山市
熊本市
鹿児島市
garbage_categories.csvには、ゴミの種類を入れます。これは、今回機械学習させた4つを登録させていきましょう。将来的には、家庭のモノの名前(例えば、ドライヤーや服)が登録されると、モノごとに何ゴミかリンクさせることができるので、一番理想の登録の仕方になります。その時には、今回のcsv読み込みができると、楽ちんですね!
name
燃えるゴミ
プラスチック
ペットボトル
段ボール
city_category_names.csvには、先ほど作ってきた都市とゴミの種類が掛け合わされた時に、その都市で何ゴミになるのかを書いていきます。これも、本来は都市×ゴミの名前がふさわしいんですが…。機械学習の際にそうしておけばよかったですね…。
city,category,display_name
札幌市,燃えるゴミ,燃やせるごみ
札幌市,プラスチック,容器包装プラスチック
札幌市,ペットボトル,ペットボトル
札幌市,段ボール,地域の資源集団回収へ
仙台市,燃えるゴミ,家庭ゴミ
・・・

ですが、これはかなり量があることに加え、エディタで書くと白字ばかりでみずらいですよね・・・。そこで、こんなプラグインを見つけてきました。列ごとに色分けをしてくれるプラグインです。インストールして使ってみると、なんとカラフル! わかりやすく作業することができました。

Djangoに読み込ませるコマンド
続いて、Djangoに読み込ませていくコマンドを作っていきます。今回作ったCSVファイルは、このコマンドを利用して、前回作ったデータベースへ読み込ませます。まずはディレクトリを以下のように作成します。
mkdir -p garbage/management/commands
touch garbage/management/__init__.py
touch garbage/management/commands/__init__.py
touch garbage/management/commands/import_data.py
ここで新しく作ったimport_data.pyには、以下のようにコードを書きます。各カテゴリーで、作ってきたCSVファイルを開いて読み込ませています。読み込みがうまくいったものについては、インポート完了と表示させることで、読み込みがうまくいったものがわかるようにしました。
import csv
from django.core.management.base import BaseCommand
from garbage.models import City, GarbageCategory, CityCategoryName
class Command(BaseCommand):
help = 'CSVファイルから市区町村・ごみ分類データをインポートします。'
def handle(self, *args, **options):
# City
with open('cities.csv', newline='', encoding='utf-8') as f:
reader = csv.DictReader(f)
for row in reader:
City.objects.get_or_create(name=row['name'])
self.stdout.write(self.style.SUCCESS('✅ City インポート完了'))
# GarbageCategory
with open('garbage_categories.csv', newline='', encoding='utf-8') as f:
reader = csv.DictReader(f)
for row in reader:
GarbageCategory.objects.get_or_create(name=row['name'])
self.stdout.write(self.style.SUCCESS('✅ GarbageCategory インポート完了'))
# CityCategoryName
with open('city_category_names.csv', newline='', encoding='utf-8') as f:
reader = csv.DictReader(f)
for row in reader:
city = City.objects.get(name=row['city'])
category = GarbageCategory.objects.get(name=row['category'])
CityCategoryName.objects.get_or_create(
city=city,
category=category,
defaults={'display_name': row['display_name']}
)
self.stdout.write(self.style.SUCCESS('✅ CityCategoryName インポート完了'))
データベースに読み込ませてみる
読み込ませる
ここまで完成したら、あとはコマンドを実行するだけでCSVファイルを読み込ませることができます。実行すると、無事に読み込ませることができました。緑の字でインポート完了!と表示されています。
python manage.py import_data

動作確認
さて、インポート完了とは表示されたものの、本当にデータベースに登録されたのかや、動作するのかは気になりますよね。ちゃんと読み込ませたCSVの内容が表示されるのか、確認してみましょう。以下のコマンドでDjangoのシェルを起動させます。
python manage.py shell
すると、Pythonの対話環境が開きますので、下記のように入力してみましょう。実際に実行してみたところ、ちゃんと動作させることができました!
from garbage.utils import get_local_garbage_name
get_local_garbage_name("札幌市", "プラスチック")
# 結果: '容器包装プラスチック'

一個一個確認していくのは大変なので、ランダムに何個かピックアップして聞いてみましょう。また、その際に存在しない登録名も試してみます。どのような返答があるのでしょうか。
以下のコードを使って試してみます。
先ほどと同じように、Djangoのシェル上でPythonでゴミの種類を聞いてみます。下の二つは、「燃えるごみ」という登録していないジャンルと、今回登録していない「長野市」という地域名を入れました。正しく動作すれば、{city(地域名)} の {category(ゴミカテゴリ)} → {result(地域でのゴミの種類)}という形で返答されてくるはずです。
from garbage.utils import get_local_garbage_name
queries = [
("千葉市", "プラスチック"),
("川崎市", "燃えるゴミ"),
("鹿児島市", "段ボール"),
("新潟市", "ペットボトル"),
("神戸市", "燃えないごみ"), # 存在しないカテゴリ
("長野市", "ペットボトル"), # 存在しないカテゴリ
]
for city, category in queries:
result = get_local_garbage_name(city, category)
print(f"{city} の {category} → {result}")
すると、無事に返答されました。千葉市のような少し長いものでも、しっかりと返答してくれていますね。
存在しないカテゴリーとして入れた神戸市の燃えないごみや、長野市のペットボトルも、登録されていないとしっかりと返してくれています。これで問題なさそうですね!

まとめ
今回はCSVファイルから、ゴミの種類と地域名、その地域ではそのゴミが何ゴミになるのか、直接読み込ませることをしてみました。結果、無事に読み込ませることができました!
今回作った内容もGitHubで公開されていますので、データベースへCSV読み込みをする際の参考にしてみてください!
今日もご覧いただき、ありがとうございました!