MySQL 到 MongoDB 数据迁移

def*_*t__ 5 python mysql data-migration mongodb pymongo

我们知道MongoDB有两种对关系/实体之间的关系进行建模的方式,即嵌入引用参见这里的区别)。假设我们有一个USER数据库,其中 mySQL 中有两个表,分别名为useraddress。嵌入式 MongoDB 文档可能如下所示:

{
  "_id": 1,
  "name": "Ashley Peacock",
  "addresses": [
    {
      "address_line_1": "10 Downing Street",
      "address_line_2": "Westminster",
      "city": "London",
      "postal_code": "SW1A 2AA"
    },
    {
      "address_line_1": "221B Baker Street",
      "address_line_2": "Marylebone",
      "city": "London",
      "postal_code": "NW1 6XE"
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

而在引用关系中,2 个 SQL 表将在 MongoDB 中生成 2 个集合,可以通过此方法使用pymongo.

如何使用python直接将MySQL数据迁移为嵌入文档?

关于伪代码和算法性能的见解将非常有用。我想到的是views通过在 MySQL 中执行来进行创建joins。但在这种情况下,我们将不会在父文档中拥有子文档的结构。

Mat*_*one 4

非规范化

首先,对于规范参考,“嵌入”数据与“参考”数据的问题称为非规范化。Mongo 有一个指南描述了何时应该进行非规范化。从 SQL 迁移到 NoSQL 时,了解何时以及如何进行非规范化是一个非常常见的难题,如果弄错了,可能会抹掉您可能寻求的任何性能优势。我假设您已经解决了这个问题,因为您似乎决定使用嵌入式方法。

MySQL 到 Mongo

Mongo 有一个很棒的Python 教程,您可能需要参考。首先加入你的useraddress表。它看起来像这样:

| _id    | name           | address_line_1        | address_line_2 | ... 
| 1      | Ashley Peacock | 10 Downing Street ... | ...
| 1      | Ashley Peacock | 221B Baker Street ... | ...
| 2      | Bob Jensen     | 343 Main Street ...   | ...
| 2      | Bob Jensen     | 1223 Some Ave ...     | ...
...
Run Code Online (Sandbox Code Playgroud)

然后迭代行以创建文档并将它们传递给pymongo insert_one. 如果在数据库中找不到匹配的文档,则使用upsert=Truewith将插入一个新文档,如果找到则更新现有文档。insert_one使用将数据$push附加到文档中的address数组字段。addresses通过此设置,insert_one将自动处理重复项并根据匹配_id字段附加地址。请参阅文档了解更多详细信息:

from pymongo import MongoClient

client = MongoClient(port=27017)
db = client.my_db

sql_data = []  # should have your SQL table data
# depending on how you got this into python, you will index with a  
# field name or a number, e.g. row["id"] or row[0] 

for row in sql_data:
    address = {
        "address_line_1": row["address_line_1"],
        "address_line_2": row["address_line_2"],
        "city": row["city"],
        "postal_code": row["postal_code"],
    }
    db.users.update_one(
        {"_id": row["_id"]},
        {"name": row["name"], "$push": {"addresses": address}},
        upsert=True,
    )
Run Code Online (Sandbox Code Playgroud)