PythonでGridFSとPyMongoを用いてMongoDBに画像を保存する

スポンサーリンク

PythonでGridFSとPyMongoを用いてMongoDBに画像を保存してみます。

なお、今回はPyMongoモジュールを用います。このライブラリ・モジュールはPythonの標準ライブラリではありませんので、事前にインストールする必要があります。

■Python

今回のPythonのバージョンは、「Python 3.9.13」を使用しています。(Windows10)

■仮想環境の構築

GridFSとPyMongoを用いてMongoDBに画像を保存してみますが、その前に仮想環境の構築を行い、インストールを行います。そのために、まずはWindows10のコマンドプロンプトを起動します。

C:\Users\user_>mkdir mongo_image

起動後、上記のコマンドを入力し、Enterキーを押します。「mkdir」コマンドで「mongo_image」ディレクトリを作成します。

C:\Users\user_>cd mongo_image

作成後、上記のコマンドを入力し、Enterキーを押します。「cd」コマンドで「mongo_image」ディレクトリ内に移動します。

C:\Users\user_\mongo_image>py -3.9 -m venv .venv

移動後、上記のコマンドを入力し、Enterキーを押します。本来だと「python -m venv .venv」で仮想環境のディレクトリ「.venv」を作成しますが、今回はPythonのバージョンを指定しています。なお、今回仮想環境のディレクトリ名は「.venv」としていますが、ご自身で変更は可能です。

Enterキーを押すと、何も出力されませんが、これで仮想環境の作成が完了となります。

■仮想環境への切り替え

C:\Users\user_\mongo_image>.venv\Scripts\activate.bat

完了後、上記のコマンドを入力し、Enterキーを押します。仮想環境のディレクトリ内に作成された activateスクリプトを実行し、仮想環境に入ります。

(.venv) C:\Users\user_\mongo_image>

Enterキーを押すと、「(.venv)」と表示されます。これで仮想環境に入ることができました。

■pymongoのインストール

(.venv) C:\Users\user_\mongo_image>pip install pymongo

仮想環境に入った後に、上記のコマンドを入力し、Enterキーを押します。これでpipを経由してpymongoをインストールします。

Collecting pymongo
  Using cached pymongo-4.2.0-cp39-cp39-win_amd64.whl (374 kB)
Installing collected packages: pymongo
Successfully installed pymongo-4.2.0
WARNING: You are using pip version 22.0.4; however, version 22.2.2 is available.
You should consider upgrading via the 'C:\Users\user_\mongo_image\.venv\Scripts\python.exe -m pip install --upgrade pip' command.

Enterキーを押すと、インストールが開始され、「Successfully installed(正常にインストールされました)」と出力されます。これが出力されればインストールは完了となります。「WARNING」も出力されているが、警告であってエラーではないので、今回は一旦無視します。

■画像を用意する

pymongoをインストール後、MongoDBに画像を保存するため、画像を用意します。

今回は「C:\Users\user_\mongo_image(フォルダパス)」内に「mountain.png」というpng形式の画像ファイルを用意しました。この画像ファイルは、フリーで高品質な画像・動画素材を提供している「Pixabay(https://pixabay.com/ja/)」から著作権フリーの画像を利用しています。

■GridFSとPyMongoを用いてMongoDBに画像を保存する

画像の用意ができましたので、GridFSとPyMongoを用いてMongoDBに画像を保存するスクリプトを書いていきます。

■コード

from pymongo import MongoClient 
import gridfs

connection = MongoClient("mongodb+srv://kazu:un43ynGWuPaYVQ6@cluster0.cywla.mongodb.net/?retryWrites=true&w=majority")

database = connection['test_db']

fs = gridfs.GridFS(database)

img_file = r"C:\Users\user_\mongo_image\mountain.png"

with open(img_file,'rb') as f:
    contents = f.read()

fs.put(contents,filename="mountani_image")

今回は「from import」でpymongoのMongoClientを呼び出します。さらにimportでgridfsも呼び出します。

その後、「connection = MongoClient()」を用いて、MongoClientを使用しMongoDBへの接続を作成します。括弧内には、今回MongoDB Cloud(https://cloud.mongodb.com/)にログインを行い、「DEPLOYMENT」の「Database」で、事前に作成した「Cluster 0」というクラスターを選択し、「Connect」ボタンをクリックする。クリックすると、「Connect to Cluster0」ウインドウが表示され、「Connect your application」を選択。選択後、「Select your driver and version」で「DRIVER」を「Python」と選択し、「VERSION」を今回は「3.6 or later」に選択する。選択すると、「Add your connection string into your application code」にコードが表示されるので、このコードをコピーし引数,パラメータとして渡す。渡す際に「mongodb+srv://username:<password>@cluster0.cywla.mongodb.net/?retryWrites=true&w=majority」の「<password>」の部分をDatabaseのパスワードに置き換えて引数,パラメータとして渡す。

MongoDBへの接続を作成した後に、databaseという変数を定義し、その中に「connection[‘test_db’]」と記述する。今回は事前に作成した「Cluster 0」というクラスター内に「test_db」というデータベースと、「collection01」というコレクションを作成しているので、「[‘test_db’]」としている。これでデータベースが指定される。

その後、fsという変数を定義し、その中でgridfs.GridFS()を用います。括弧内には、database変数を引数,パラメータとして渡します。これでGridFSの新しいインスタンスが作成されます。

作成後、img_fileという変数を定義し、その中に今回用意した画像ファイルの名前を置かれている場所を格納します。

格納後、with構文とopen()を用います。open()の括弧内の第1の引数,パラメータとしてimg_file変数を渡します。次に第2の引数,パラメータとして”rb”を渡します。これで開いたものをバイナリファイルとして読み込むモードになります。バイナリファイルとして読み込んだものをf変数に格納します。その後、contentsという変数を定義し、その中にf変数に対してread()を用います。これで格納されたものを読み込んでcontents変数へ格納します。

最後にfs.put()を用います。括弧内には第1の引数,パラメータとしてcontents変数を渡します。次に第2の引数,パラメータとしてfilenameを渡します。これでデータを新しいファイルとしてGridFSに入れます。GridFSは、画像、オーディオ ファイル、ビデオファイルなどの大きなファイルを格納および取得するためのMongoDBの仕様です。

このスクリプトを、「mongo_image」ディレクトリ内に「db_imagefile.py」という名前で保存します。

■実行・検証

保存後、コマンドプロンプト上で仮想環境に入った状態でスクリプトファイルを実行してみます。

(.venv) C:\Users\user_\mongo_image>python db_imagefile.py
Traceback (most recent call last):
  File "C:\Users\user_\mongo_image\db_imagefile.py", line 4, in 
    connection = MongoClient("mongodb+srv://kazu:un43ynGWuPaYVQ6@cluster0.cywla.mongodb.net/?retryWrites=true&w=majority")
  File "C:\Users\user_\mongo_image\.venv\lib\site-packages\pymongo\mongo_client.py", line 726, in __init__
    res = uri_parser.parse_uri(
  File "C:\Users\user_\mongo_image\.venv\lib\site-packages\pymongo\uri_parser.py", line 469, in parse_uri
    raise ConfigurationError(
pymongo.errors.ConfigurationError: The "dnspython" module must be installed to use mongodb+srv:// URIs. To fix this error install pymongo with the srv extra:
 C:\Users\user_\mongo_image\.venv\Scripts\python.exe -m pip install "pymongo[srv]"

スクリプトを実行してみると、「pymongo.errors.ConfigurationError」というエラーが発生しました。エラー内容を確認すると、dnspythonモジュールがインストールされていないことが原因と判明。

(.venv) C:\Users\user_\mongo_image>pip install "pymongo[srv]"

判明後、上記のコマンドを入力し、Enterキーを押します。これでdnspythonモジュールがインストールされます。

Requirement already satisfied: pymongo[srv] in c:\users\user_\mongo_image\.venv\lib\site-packages (4.2.0)
Collecting dnspython<3.0.0,>=1.16.0
Using cached dnspython-2.2.1-py3-none-any.whl (269 kB)
Installing collected packages: dnspython
Successfully installed dnspython-2.2.1

Enterキーを押すと、インストールが開始され、「Successfully installed(正常にインストールされました)」と出力されます。これが出力されればdnspythonのインストールは完了となります。

(.venv) C:\Users\user_\mongo_image>python db_imagefile.py

完了後、再度上記のコマンドを入力し、Enterキーを押してみます。

Enterキーを押すと、何も出力されませんが、先程のエラーは出力されず、MongoDBに画像が保存されました。

保存後、MongoDB Cloud(https://cloud.mongodb.com/)にログインを行い、「DEPLOYMENT」の「Database」で、事前に作成した「Cluster 0」というクラスターを選択し、「Browse Collections」ボタンをクリックします。クリックすると、Database内のCollectionsなどを確認できますが、この中に「fs.files」と「fs.chunks」という2つのコレクションが追加されていることが確認できました。

この2つのコレクションは、画像ファイルのメタデータとチャンクが格納されています。各チャンクは、一意の「_id ObjectId」フィールドによって識別されています。「fs.files」のコレクションは親ドキュメントとして機能し、「fs.chunks」のコレクションの「files_id」フィールドは、チャンクを親である「fs.files」にリンクしています。なおチャンクとは、キー範囲とそのキー範囲が関連するシャードを記述する小さなレコードです。シャードとは、複数のマシンにデータを分散または分割する方法です。

 

コメント

タイトルとURLをコピーしました