AI エージェント向け: ドキュメントインデックスは https://www.mongodb.com/ja-jp/docs/llms.txt で利用できます。すべてのページの markdown バージョンは、いずれかの URL パスに .md を追加することで利用できます。

チュートリアル: SQLからMongoDBへのFlaskの移行する

このチュートリアルでは、FlaskアプリケーションをSQLからMongoDBに移行する方法を説明します。具体的には、このチュートリアルでは、SQLAlchemy を使用する例のブログアプリケーションを、Flask- PyMongo を使用するものに変換します。

この例アプリケーションには、次の機能が含まれています。

  • ブログ記事の作成、編集、表示

  • ブログ記事の検索

MongoDB は、ドキュメントにデータを保存する NoSQLデータベースです。以下のリストでは、 MongoDB の主要な概念を説明しています。

  • コレクション: SQLデータベースのテーブルに似たドキュメントのグループ。コレクションはスキーマを強制しません。

  • ドキュメント: データを保存するJSONのようなオブジェクト。ドキュメントには配列やネストされたサブドキュメントを含めることができます。

  • BSON: MongoDB が内部的に使用するバイナリJSON形式。BSON は、日付やバイナリなどの追加のデータ型でJSONを拡張したものです。

次の表は、 MongoDBデータベースとSQLデータベースを比較したものです。

機能
SQL
MongoDB

スキーマ

事前定義されたテーブルと列を含む固定スキーマを強制

動的データモデルを可能にする柔軟なスキーマ

データ構造

行と列を含むテーブルにデータを保存

ドキュメントのコレクションにデータを保存

関係

テーブル間の関係を確立するために外部キーと結合を使用します

ドキュメントを他のドキュメントに埋め込みます。または参照します。結合は必要ありません

クエリ言語

構造化クエリ言語の使用(SQL)

豊富なJSONベースのクエリ言語を使用

このチュートリアルでは、次の手順を実行する方法について説明します。

  • 前提条件を確認します

  • フラグのインストール- PyMongo

  • [Flask]アプリケーションモデルを更新します

  • [Flask]アプリケーション構成を更新します

  • [Flask]アプリケーションルートを更新します

  • SQLite からのデータのエクスポート

  • MongoDBへのデータのインポート

  • [Flask] テンプレートを更新します

  • 移行したアプリケーションの実行

1

このチュートリアルには次の前提条件が必要です。

  • MongoDB はローカルマシンにインストールされています。手順については、 MongoDB Serverマニュアルの「 MongoDB のインストール 」ガイドを参照してください。

  • SQLAlchemy を使用する既存の Fluskアプリケーション。このチュートリアルでは、GitHub の flask-mongo リポジトリの例フラグアプリケーションを使用できます。

  • Python 3.7 以降。

flask-mongo例アプリケーションには、flask-mongo と flask-sql の 2 つのサブフォルダが含まれています。flask-sql フォルダーには、このチュートリアルの移行に使用できる SQLAlchemy を使用する Flukアプリケーションが含まれています。

移行を開始 する前に、次のアクションを完了してください。

  1. テーブル、関係、データ型など、SQLデータベーススキーマを検討します。

  2. MongoDBで特別な処理を必要とする複雑なクエリと関係を識別します。

  3. データベースの ドキュメント指向 を考慮してMongoDBスキーマを設計します。MongoDBでのスキーマ設計の詳細については、 MongoDB Serverマニュアルの「スキーマの設計」ガイドを参照してください。

  4. 現在のSQLデータベースの完全なバックアップを作成します 。

2

Flusk- PyMongoは、 MongoDB をFlusk アプリケーションと統合する Flusk 拡張機能です。

以下のコマンドを実行中して、Flask- PyMongoをインストールします。

pip install Flask-PyMongo Flask
3

models.pyファイルの内容を次のコードで置き換えます。

from datetime import datetimefrom bson.objectid import ObjectId class Post: def __init__(self, title, content, date_posted=None, _id=None): self.title = title self.content = content self.date_posted = date_posted if date_posted \ else datetime.utcnow() self._id = _id if _id else ObjectId() def to_dict(self): return { "title": self.title, "content": self.content, "date_posted": self.date_posted, "_id": self._id } @staticmethod def from_dict(data): return Post( title=data.get('title'), content=data.get('content'), date_posted=data.get('date_posted'), _id=data.get('_id') ) def __repr__(self): return f"Post('{self.title}', \ '{self.date_posted}')"

このコードでは、 MongoDBのブログ記事をモデル化する Postクラスを定義します。クラスには、次のメソッドが含まれています。

  • __init__: 各書き込みのタイトル、内容、書き込み日付、一意の識別子を設定

  • to_dict:インスタンスをMongoDBストレージの辞書に変換

  • from_dict: 辞書から Postインスタンスを作成します

  • __repr__: 書き込みの string 表現を返します

4

__init__.pyファイルの内容を次のコードで置き換えます。

from flask import Flaskfrom flask_pymongo import PyMongofrom config import Config app = Flask(__name__)app.config.from_object(Config)mongo = PyMongo(app) from app import routes

このコードは、Flaskアプリケーションを初期化し、Flask- PyMongo拡張機能を通じてMongoDBを使用するようにします。

次のコードを追加して、MongoDB設定を含むように config.pyファイルを更新します。

import os class Config: SECRET_KEY = os.urandom(24) MONGO_URI = 'mongodb://localhost:27017/blogdb'

manage.pyファイルを削除します。このファイルはSQLのデータベース移行に使用しますが、 MongoDBには適用されません。

注意

MongoDB の移行が必要な場合は、Beanie ODM が移行のサポートを提供します。

5

routes.pyファイルの内容を次のコードで置き換えます。

from flask import render_template, url_for, flash, \ redirect, requestfrom app import app, mongofrom bson.objectid import ObjectIdfrom app.models import Postfrom app.forms import PostForm @app.route("/")@app.route("/home")def home(): posts_data = mongo.db.posts.find() posts = [Post.from_dict(post) for post in posts_data] return render_template("index.html", posts=posts) @app.route("/post/new", methods=["GET", "POST"])def new_post(): form = PostForm() if form.validate_on_submit(): post = Post(title=form.title.data, content=form.content.data) mongo.db.posts.insert_one(post.to_dict()) flash("Your post has been created!", "success") return redirect(url_for("home")) return render_template("post.html", title="New Post", form=form) @app.route("/post/<post_id>")def post(post_id): post_data = mongo.db.posts.find_one_or_404( {"_id": ObjectId(post_id)}) post = Post.from_dict(post_data) return render_template("detail.html", post=post) @app.route("/post/<post_id>/edit", methods=["GET", "POST"])def edit_post(post_id): post_data = mongo.db.posts.find_one_or_404( {"_id": ObjectId(post_id)}) post = Post.from_dict(post_data) form = PostForm() if form.validate_on_submit(): updated_post = { "$set": {"title": form.title.data, "content": form.content.data} } mongo.db.posts.update_one( {"_id": ObjectId(post_id)}, updated_post) flash("Your post has been updated!", "success") return redirect(url_for("post", post_id=post_id)) elif request.method == "GET": form.title.data = post.title form.content.data = post.content return render_template("edit_post.html", title="Edit Post", form=form) @app.route("/post/<post_id>/delete", methods=["POST"])def delete_post(post_id): mongo.db.posts.delete_one({"_id": ObjectId(post_id)}) flash("Your post has been deleted!", "success") return redirect(url_for("home")) @app.route("/search", methods=["GET", "POST"])def search(): query = request.args.get("query") posts_data = mongo.db.posts.find( { "$or": [ {"title": {"$regex": query, "$options": "i"}}, {"content": {"$regex": query, "$options": "i"}}, ] } ) posts = [Post.from_dict(post) for post in posts_data] return render_template("index.html", posts=posts)

このコードでは、SQLAlchemy の代わりにMongoDBを使用するようにルートを更新します。ルートは次のアクションを完了します。

  • MongoDBでのストレージに to_dict メソッドを使用して、Post インスタンスを辞書に変換する

  • 次を使用して書き込みを検索する mongo.db.posts.find()

  • を使用して書き込みを挿入 mongo.db.posts.insert_one()

  • 次を使用して書き込みを更新します mongo.db.posts.update_one()

  • 次を使用して書き込みを削除します mongo.db.posts.delete_one()

  • MongoDB の正規表現機能を使用して投稿を検索

6

export_list_tables.py という名前のPythonスクリプトを作成し、次のコードを新しいファイルに追加して、SQLiteデータベース内のすべてのテーブルを一覧表示します。

import sqlite3 # Connect to the SQLite databasedb_path = 'relative/path/to/site.db'conn = sqlite3.connect(db_path)cursor = conn.cursor() # Query to get all table namescursor.execute("SELECT name FROM sqlite_master WHERE \ type='table';")tables = cursor.fetchall() # Close the connectionconn.close() print(tables)

このスクリプトを実行して、テーブル名を表示します。出力には post テーブルが表示されます。

データをJSONにエクスポートするには、次のコードを新しいファイルに追加して、export_to_json.py という名前の別のPythonスクリプトを作成します。

import sqlite3import json # Connect to the SQLite databasedb_path = 'relative/path/to/site.db'conn = sqlite3.connect(db_path)cursor = conn.cursor() # Export data from the 'post' tablecursor.execute("SELECT * FROM post")rows = cursor.fetchall() # Get the column namescolumn_names = [description[0] for description in \ cursor.description] # Convert to list of dictionariesdata = [dict(zip(column_names, row)) for row in rows] # Save to a JSON filewith open('post.json', 'w') as f: json.dump(data, f, indent=4) # Close the connectionconn.close()

次のスクリプトを実行して、現在のディレクトリに post.jsonファイルを作成します。このファイルには、 JSON形式のエクスポートされたデータが含まれています。

7

import_to_mongo.py という名前のPythonスクリプトを作成し、次のコードを新しいファイルに追加して、 JSONファイルをMongoDBにインポートします。

from pymongo import MongoClientimport jsonfrom datetime import datetime def import_json_to_mongo(db_name, collection_name, json_path): client = MongoClient("mongodb://localhost:27017/") db = client[db_name] def convert_date(data): # Update 'date_posted' field to datetime object for item in data: if 'date_posted' in item: item['date_posted'] = datetime.strptime( item['date_posted'], '%Y-%m-%d %H:%M:%S.%f') return data with open(json_path, 'r') as f: data = json.load(f) data = convert_date(data) db[collection_name].insert_many(data) client.close() if __name__ == "__main__": db_name = 'blogdb' collection_name = 'posts' json_path = 'flask-mongo/post.json' import_json_to_mongo(db_name, collection_name, json_path)

このスクリプトを実行して、データをMongoDBにインポートします。スクリプトはdate_postedフィールドを日時オブジェクトに変換し、すべての書き込みをMongoDBコレクションに挿入します。

注意

接続文字列mongodb://localhost:27017/blogdb は、ポート 27017 にあるローカルホスト上のMongoDBインスタンスに接続します。MongoDB は最初にデータを書き込むと、データベースを自動的に作成します。

8

MongoDBドキュメントIDを使用するようにテンプレート ファイルを更新し、post_id=post.id のすべてのインスタンスを post_id=post._id に変更します。

9

次のコマンドを実行して、Flaskアプリケーションを実行します。

python run.py

ウェブ ブラウザで http://127.0.0.1:5000/home に移動すると、アプリケーションにアクセスできます。

[Flask-Pymongo] の詳細については、Flask- PyMongoに関するドキュメントを参照してください。