Python を使用して MySQL テーブル データを MongoDB コレクションに移行する方法

Python を使用して MySQL テーブル データを MongoDB コレクションに移行する方法

[[410477]]

【51CTO.com クイック翻訳】はじめに

MySQL は、データを正規化された方法で表形式で保存する RDBMS プラットフォームですが、MongoDB は、コレクションにグループ化されたドキュメントとしてスキーマレスな方法で情報を保存する NoSQL データベースです。データの表現方法が完全に異なるため、MySQL テーブル データを MongoDB コレクションに移行するのは困難な作業のように思えるかもしれません。しかし、Python は強力な接続性とデータ処理機能を備えているため、これを簡単に実現できます。

この記事では、簡単な Python スクリプトを使用して MySQL テーブル データを MongoDB コレクションに移行するために必要な手順を詳しく説明します。スクリプトは Windows 上の Python 3.9.5 を使用して開発されました。ただし、どのプラットフォームでも Python 3 以降のバージョンで動作するはずです。

ステップ1: 必要なモジュールをインストールする

最初のステップは、MySQL および MongoDB データベース インスタンスに接続するために必要なモジュールをインストールすることです。 MySQL データベースに接続するには、 mysql.connectorを使用します。 MongoDB の場合は、Python から MongoDB に接続するための推奨モジュールであるpymongo を使用します。

必要なモジュールがまだインストールされていない場合は、次の PIP コマンドを実行してインストールします。

  1. pip mysqlコネクタをインストール pip pymongoをインストール

PIP は、Python パッケージまたはモジュール用のパッケージ マネージャーです。

ステップ2: MySQLテーブルからデータを読み取る

最初のステップは、ソース MySQL テーブルからデータを読み取り、ターゲット MongoDB データベースにデータをロードするために使用できる形式で準備することです。 MongoDB はデータを JSON ドキュメントとして保存する NoSQL データベースなので、ソース データを JSON 形式で生成するのが最適です。 Python には強力なデータ処理機能があり、データを JSON 形式に簡単に変換できることは注目に値します。

  1. mysql.connectorをインポートする
  2. mysqldb = mysql.connector.connect( ホスト = "localhost" 、データベース = "employees" 、ユーザー = "root" 、パスワード = "" )
  3. mycursor = mysqldb.cursor(dictionary= True ) mycursor.execute( "SELECT * from Categories;" ) myresult = mycursor.fetchall()
  4. 印刷(myresult)

スクリプトがエラーなしで完了すると、出力は次のようになります。

  1. [
  2. {
  3. 「id」 : 4 ,
  4. 「名前」「薬」
  5. 「説明」 : 「<p>医薬品<br></p>」
  6. "作成日時" : "" ,
  7. 「更新日時」 : 「」
  8. },
  9. {
  10. 「id」 : 6 ,
  11. 「名前」「食べ物」
  12. 「説明」 : 「<p>食品</p>」
  13. "作成日時" : "" ,
  14. 「更新日時」 : 「」
  15. },
  16. {
  17. 「id」 : 8
  18. 「名前」「食料品」
  19. 「説明」 : 「<p>食料品<br></p>」
  20. "作成日時" : "" ,
  21. 「更新日時」 : 「」
  22. },
  23. {
  24. 「id」 : 9
  25. 「名前」「ケーキ&焼き菓子」
  26. 「説明」 : 「<p>ケーキと焼き菓子<br></p>」
  27. 「作成日時」 :d 「」
  28. 「更新日時」 : 「」
  29. }
  30. ]

dictionary=Trueパラメータをカーソルに渡したため、出力は JSON 配列になることに注意してください。それ以外の場合、結果はリスト形式になります。ソース データが JSON 形式で取得できたので、それを MongoDB コレクションに移行できます。

ステップ3: MongoDBコレクションに書き込む

JSON 形式でソース データを取得したら、次のステップではそのデータを MongoDB コレクションに挿入します。コレクションはドキュメントのグループであり、RDBMS のテーブル (またはリレーション) に相当します。これは、コレクション クラスのinsert_many()メソッドを呼び出すことによって実行できます。このメソッドは、挿入されたドキュメントのオブジェクト ID のリストを返します。このメソッドは、空のリストが引数として渡されると例外をスローするため、メソッド呼び出しの前に長さのチェックが行われることに注意してください。

  1. pymongoをインポートする
  2. mongodb_host = "mongodb://localhost:27017/"
  3. mongodb_dbname = "mymongodb"
  4. myclient = pymongo.MongoClient(mongodb_host)
  5. mydb = myclient[mongodb_db名]
  6. mycol = mydb[ "カテゴリ" ]
  7. len(myresult) > 0 の場合:
  8. x = mycol.insert_many(myresult) #myresultはmysqlカーソルから取得されます
  9. 印刷(len(x.inserted_ids))

この手順を完了したら、MongoDB インスタンスをチェックして、データベースとコレクションが作成され、ドキュメントが挿入されたことを確認します。 MongoDB はスキーマレスであるため、ドキュメントを挿入するためにスキーマを定義する必要はなく、スキーマは動的に推測され、自動的に作成されることに注意してください。 MongoDB は、コード内で参照されるデータベースやコレクションがまだ存在しない場合は、それらを作成することもできます。

ステップ4: データをまとめる

以下は、MySQL からテーブルを読み取り、それを MongoDB のコレクションに挿入する完全なスクリプトです。

  1. mysql.connectorをインポートする
  2. pymongoをインポートする
  3. 既存のドキュメントを削除する = True
  4. mysql_host = "ローカルホスト"
  5. mysql_database= "mydatabase"
  6. mysql_schema = "myschema"
  7. mysql_user = "myuser"
  8. mysql_password= "********"
  9. mongodb_host = "mongodb://localhost:27017/"
  10. mongodb_dbname = "mymongodb"
  11. mysqldb = mysql.connector.connect(
  12. ホスト=mysql_host、
  13. データベース=mysql_database、
  14. ユーザー=mysql_user、
  15. パスワード=mysql_password
  16. mycursor = mysqldb.cursor(辞書 = True )
  17. mycursor.execute( "カテゴリから * を選択;" )
  18. myresult = mycursor.fetchall()
  19. myclient = pymongo.MongoClient(mongodb_host)
  20. mydb = myclient[mongodb_db名]
  21. mycol = mydb[ "カテゴリ" ]
  22. len(myresult) > 0 の場合:
  23. x = mycol.insert_many(myresult) #myresultはmysqlカーソルから取得されます
  24. 印刷(len(x.inserted_ids))

ステップ5: MySQLスキーマ内のすべてのテーブルをロードするようにスクリプトを強化する

このスクリプトは、MySQL からテーブルを読み取り、その結果を MongoDB コレクションにロードします。次のステップでは、ソース データベース内のすべてのテーブルのリストを反復処理し、結果を新しい MySQL コレクションにロードします。これは、特定のスキーマ内のテーブルのリストを提供する information_schema.tables メタデータ テーブルをクエリすることで実行できます。その後、結果を反復処理し、上記のスクリプトを呼び出して各テーブルのデータを移行できます。

  1. #スキーマ内のテーブルのリストを反復処理する
  2. table_list_cursor = mysqldb.cursor()
  3. table_list_cursor.execute( "SELECT table_name FROM information_schema.tables WHERE table_schema = %s ORDER BY table_name;" , (mysql_schema,))
  4. テーブル = table_list_cursor.fetchall()
  5. テーブル内のテーブルの場合:
  6. #「テーブル」の移行スクリプトを実行する

これは、移行ロジックを関数に抽象化することによっても実現できます。

  1. #関数 migrate_table
  2. def migrate_table(db, col_name):
  3. mycursor = db.cursor(辞書 = True )
  4. mycursor.execute( "SELECT * FROM " + col_name + ";" )
  5. myresult = mycursor.fetchall()
  6. mycol = mydb[列名]
  7. 既存のドキュメントを削除する場合:
  8. #コレクション内のすべてのドキュメントを削除する
  9. mycol.delete_many({})
  10. #ドキュメントを挿入する
  11. len(myresult) > 0 の場合:
  12. x = mycol.insert_many(myresult)
  13. len(x.inserted_ids)を返す
  14. それ以外
  15. 0を返す

ステップ6: スクリプトの進行状況を出力して読みやすくする

スクリプトの進行状況は、print ステートメントを使用して伝達されます。色分けにより出力を読みやすくします。たとえば、成功したステートメントを緑色で印刷し、失敗したステートメントを赤色で印刷します。

  1. クラスbcolors:
  2. ヘッダー = '\033[95m'
  3. OKBLUE = '\033[94m'
  4. OKCYAN = '\033[96m'
  5. OKGREEN = '\033[92m'
  6. 警告 = '\033[93m'
  7. 失敗 = '\033[91m'
  8. ENDC = '\033[0m'
  9. 太字 = '\033[1m'
  10. 下線 = '\033[4m'
  11. print (f "{bcolors.HEADER}これはヘッダーです{bcolors.ENDC}" )
  12. print (f "{bcolors.OKBLUE}これは青色で印刷されます{bcolors.ENDC}" )
  13. print (f "{bcolors.OKGREEN}このメッセージは緑です{bcolors.ENDC}" )

最終結果

  • ソース MySQL データベース
  • 移行後のターゲット MongoDB データベース
  • VSCode での Python スクリプトと出力

完全なスクリプト

  1. mysql.connectorをインポートする
  2. pymongoをインポートする
  3. 日時をインポート
  4. クラスbcolors:
  5. ヘッダー = '\033[95m'
  6. OKBLUE = '\033[94m'
  7. OKCYAN = '\033[96m'
  8. OKGREEN = '\033[92m'
  9. 警告 = '\033[93m'
  10. 失敗 = '\033[91m'
  11. ENDC = '\033[0m'
  12. 太字 = '\033[1m'
  13. 下線 = '\033[4m'
  14. begin_time = datetime.datetime.now()
  15. print (f "{bcolors.HEADER}スクリプトは{begin_time} {bcolors.ENDC}に開始されました" )
  16. 既存のドキュメントを削除します。
  17. mysql_host = "ローカルホスト"
  18. mysql_database= "mydatabase"
  19. mysql_schema = "myschema"
  20. mysql_user = "ルート"
  21. mysql_password=""
  22. mongodb_host = "mongodb://localhost:27017/"
  23. mongodb_dbname = "mymongodb"
  24. print (f "{bcolors.HEADER}データベース接続を初期化しています...{bcolors.ENDC}" )
  25. 印刷("")
  26. #MySQL接続
  27. print (f "{bcolors.HEADER}MySQL サーバーに接続しています...{bcolors.ENDC}" )
  28. mysqldb = mysql.connector.connect(
  29. ホスト=mysql_host、
  30. データベース=mysql_database、
  31. ユーザー=mysql_user、
  32. パスワード=mysql_password
  33. print (f "{bcolors.HEADER}MySQL サーバーへの接続に成功しました。{bcolors.ENDC}" )
  34. #MongoDB 接続
  35. print (f "{bcolors.HEADER}MongoDB サーバーに接続しています...{bcolors.ENDC}" )
  36. myclient = pymongo.MongoClient(mongodb_host)
  37. mydb = myclient[mongodb_db名]
  38. print (f "{bcolors.HEADER}MongoDB サーバーへの接続に成功しました。{bcolors.ENDC}" )
  39. print (f "{bcolors.HEADER}データベース接続が正常に初期化されました。{bcolors.ENDC}" )
  40. #移行を開始
  41. print (f "{bcolors.HEADER}移行が開始されました...{bcolors.ENDC}" )
  42. dblist = myclient.list_database_names()
  43. dblistmongodb_dbnameがある場合:
  44. print (f "{bcolors.OKBLUE}データベースが存在します。{bcolors.ENDC}" )
  45. それ以外
  46. print (f "{bcolors.WARNING}データベースが存在しません。作成中です。{bcolors.ENDC}" )
  47. #関数 migrate_table
  48. def migrate_table(db, col_name):
  49. mycursor = db.cursor(辞書 = True )
  50. mycursor.execute( "SELECT * FROM " + col_name + ";" )
  51. myresult = mycursor.fetchall()
  52. mycol = mydb[列名]
  53. 既存のドキュメントを削除する場合:
  54. #コレクション内のすべてのドキュメントを削除します
  55. mycol.delete_many({})
  56. #ドキュメントを挿入する
  57. len(myresult) > 0 の場合:
  58. x = mycol.insert_many(myresult)
  59. len(x.inserted_ids)を返す
  60. それ以外
  61. 0を返す
  62. #スキーマ内のテーブルのリストを反復処理する
  63. table_list_cursor = mysqldb.cursor()
  64. table_list_cursor.execute( "SELECT table_name FROM information_schema.tables WHERE table_schema = %s ORDER BY table_name LIMIT 15;" , (mysql_schema,))
  65. テーブル = table_list_cursor.fetchall()
  66. total_count = len(テーブル数)
  67. 成功回数 = 0
  68. 失敗回数 = 0
  69. テーブル内のテーブルの場合:
  70. 試す
  71. print (f "{bcolors.OKCYAN}処理テーブル: {table[0]}...{bcolors.ENDC}" )
  72. 挿入された数 = migrate_table(mysqldb、テーブル[ 0 ])
  73. print (f "{bcolors.OKGREEN}テーブル {table[0]} の処理が完了しました。{inserted_count} 個のドキュメントが挿入されました。{bcolors.ENDC}" )
  74. 成功回数 += 1
  75. except例外を e として:
  76. print (f "{bcolors.FAIL} {e} {bcolors.ENDC}" )
  77. 失敗回数 += 1
  78. 印刷("")
  79. print ( "移行が完了しました。" )
  80. print (f "{bcolors.OKGREEN}{success_count} / {total_count} 個のテーブルが正常に移行されました。{bcolors.ENDC}" )
  81. fail_count > 0の場合:
  82. print (f "{bcolors.FAIL}{fail_count} テーブルの移行に失敗しました。上記のエラーを参照してください。{bcolors.ENDC}" )
  83. 終了時刻 = datetime.datetime.now()
  84. print (f "{bcolors.HEADER}スクリプトは次の時刻に完了しました: {end_time} {bcolors.ENDC}" )
  85. print (f "{bcolors.HEADER}合計実行時間: {end_time-begin_time} {bcolors.ENDC}" )

警告する

このスクリプトは、数百のテーブルとテーブルあたり数千の行を持つ小規模から中規模の MySQL データベースに適しています。数百万行の大規模なデータベースの場合、パフォーマンスに影響が出る可能性があります。実際の移行を開始する前に、テーブル リスト クエリと実際のテーブル選択クエリの両方で LIMIT キーワードを使用して、制限された行を検出します。

ダウンロード

スクリプト全体は、GitHub からダウンロードできます。
https://github.com/zshameel/MySQL2MongoDB

[51CTOによる翻訳。パートナーサイトに転載する場合は、元の翻訳者と出典を51CTO.comとして明記してください。

<<:  IBM、マルチクラウド プラットフォームで実行される AI モデル用の CodeFlare フレームワークをオープンソース化

>>:  2021年上半期:分散クラウドについて

推薦する

プライベートクラウドの構築には、ALLINONE と階層独立構築・最適化のどちらを使うべきでしょうか?

プライベート クラウドを構築するには 2 つのアプローチがあります。 1 つは、ALLINONE ア...

クラウドネットワークとは何ですか?

クラウドの未来は明るい。 2024 年までに、IT 支出の 45% 以上が、レガシー ネットワークの...

物理マシン上でカオス実験を実行するにはどうすればよいでしょうか?

[[426176]] [51CTO.com クイック翻訳] Chaos Mesh® は、Kubern...

エッジ コンピューティングとクラウド コンピューティング: どちらがより効率的ですか?

クラウド コンピューティングは、企業にリモート データ サーバー上の情報を保存、管理、分析する機会を...

raksmart: 香港のクラウドシミュレーション携帯電話、リアルタイムのオンライングループ制御、マルチシナリオのビジネスニーズを満たす

raksmartは香港データセンターで香港クラウドフォン事業を開始しました。香港クラウドシミュレーシ...

Webmaster.comからの日報:タオバオはO2Oに注力しており、共同購入サイトの数は500に減少

1. Sina Weibo: ユーザーエクスペリエンスの悪化と商業化の学習能力の欠如Sina Wei...

西起胡同における外部リンク構築の盲点を解明

最近、オフサイトのプロモーション作業をいくつか行っていますが、プロモーション中にいくつかの小さな詳細...

外部リンクを送信しなくてもウェブサイトを宣伝できます

ウェブマスターやウェブサイト運営者なら誰でも、できるだけ早く自分のウェブサイトをインターネットの隅々...

忘れられない物語を伝えるにはどうすればいいでしょうか?

コンテンツ マーケティングの本質は自慢することです。たとえひざまずかなければならないとしても、自分が...

エッジコンピューティングとフォグコンピューティングの台頭は画期的な技術となった

今日、仮想化サービスの人気の高まりからクラウド コンピューティング サービス プラットフォームの広範...

nodeserv-$4.5/バックアップ/大容量メモリ/RDP/VP-N オールインワン

Nodeserv は今回、何か新しいものをもたらしました。少なくともプロモーション オプションは増え...

ブログの発展の現状は「止める自由」の観点からは弱い

一昨日、つまり3月31日、China Blog Networkはすべての無料ユーザーのデータとテキス...

5月の最終週に、中国の.COMドメインの総数は12,000増加したが、米国では26,000減少した。

IDC Review Network (idcps.com) は 6 月 5 日に次のように報告しま...

hosteons: VPS 20% 割引クーポン (流通)、中国語 Windows、無制限トラフィック

Hosteons は 12 月に新しい 20% 割引コードを開始しました。この VPS プロモーショ...

Renren Videoが正式に閉鎖を発表

12月20日午前、人人影事字幕ステーションはWeiboに人人影事の閉鎖を正式に発表し、今後も正規の商...