def*_*t__ 5 python mysql data-migration mongodb pymongo
我们知道MongoDB有两种对关系/实体之间的关系进行建模的方式,即嵌入和引用(参见这里的区别)。假设我们有一个USER数据库,其中 mySQL 中有两个表,分别名为user和address。嵌入式 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。但在这种情况下,我们将不会在父文档中拥有子文档的结构。
首先,对于规范参考,“嵌入”数据与“参考”数据的问题称为非规范化。Mongo 有一个指南描述了何时应该进行非规范化。从 SQL 迁移到 NoSQL 时,了解何时以及如何进行非规范化是一个非常常见的难题,如果弄错了,可能会抹掉您可能寻求的任何性能优势。我假设您已经解决了这个问题,因为您似乎决定使用嵌入式方法。
Mongo 有一个很棒的Python 教程,您可能需要参考。首先加入你的user和address表。它看起来像这样:
| _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)