【ArchSummit架构师峰会】探讨数据与人工智能相互驱动的关系>>> 了解详情
写点什么

使用 Python 将 MongoDB 数据导到 MySQL

  • 2018-12-17
  • 本文字数:3467 字

    阅读完需:约 11 分钟

使用Python将MongoDB数据导到MySQL

MySQL Shell 8.0.13(GA)引入了一项新功能,让你可以轻松地将 JSON 文档导入到 MySQL。这篇文章将介绍这项功能的实际用例:如何将 MongoDB 中的 JSON 数据导入 MySQL。这些方法同样适用于将数据从其他文档存储数据库导入 MySQL,只要它们能够生成或导出 JSON 数据。


无论出于何种原因,在迁移到不同的数据库时都不应该掉以轻心,在某些情况下还可能会非常复杂。在其他方面,它取决于数据库服务器的数量及它们在系统中的组织方式(单一服务器还是复杂的复制拓扑)、数据大小、执行迁移任务的要求和可用资源。为了确保迁移成功,需要制定全面详细的计划,计划中应该包括所有必需的步骤和相应的操作和工具。


不同的场景需要不同的迁移计划,但它们可能会包括一些通用的步骤,例如更新应用程序,让它们使用新的数据库,以及导出和导入数据库数据。MySQL Shell 提供的用于导入 JSON 数据的新功能有助于我们以更简单的方式完成这些任务。接下来让我们看看如何使用 Python 将数据从 MongoDB 导入到 MySQL。

将数据从 MongoDB 导出到 JSON

MongoDB 允许你将所有数据导出到 JSON,但它会生成遵循严格模式表示的MongoDB Extended JSON。好在 MySQL Shell JSON 导入功能为我们提供了“convertBsonOid”选项,可以轻松转换 BSON ObjectId 类型。


注意:如果你的数据包含除 ObjectId 之外的其他 BSON 类型,它们以严格模式表示(例如,BinData、Date、Timestamp、NumberLong、NumberDecimal 等),那么你可能需要根据你的需求手动转换这些类型(例如,在导入/导出过程中使用自定义转换脚本,或在应用程序级别转换它们)。有关 BJSON 类型及其在严格模式下的表示的更多信息,请参阅:BSON数据类型和相关表示


首先,你需要将所有 MongoDB 数据导出到 JSON 文档。例如,假设你在“test”数据库中有两个集合,名为 restaurants 和 neighboors。你可以使用以下命令将 MongoDB 数据导出到 JSON 文档(每个集合对应一个文件):


$ mongoexport --db test --collection restaurants --out restaurants_mongo.json2018-10-08T18:38:19.104+0100 connected to: localhost2018-10-08T18:38:19.633+0100 exported 25359 records $ mongoexport --db test --collection neighborhoods --out neighborhoods_mongo.json2018-10-08T18:38:45.923+0100 connected to: localhost2018-10-08T18:38:46.382+0100 exported 195 records
复制代码


你将得到两个包含导出数据的 JSON 文件“restaurants_mongo.json”和“neighborhoods_mongo.json”。

使用 Python 将 JSON 数据导入 MySQL

接下来,你只需使用 MySQL Shell 的新功能将生成的 JSON 文件导入到 MySQL 数据库。我们将在下一个示例中使用 Python 函数“util.import_json”。



命令:


> \py > util.import_json("/path_to_file/neighborhoods_mongo.json", {"schema": "test", "collection": "neighborhoods", "convertBsonOid": True}) > util.import_json("/path_to_file/restaurants_mongo.json", {"schema": "test", "table": "restaurants", "convertBsonOid": True})
复制代码


“convertBsonOid”选项被设置为 true,导入的两个文件中的 MongoDB Object Id(OID)被转换为正确的值。在将 JSON 数据导入到集合时,这是必需的,因为 OID 被转换为 MySQL 用于标识每个文档的集合 Id(更具体地说,“_id”列和“_id”字段用于标识集合中的每个文档),否则在尝试将包含 OID 的字段导入到集合中的 MySQL 文档 Id(“_id”)时将发出错误。


使用 Python 函数 util.import_json()将第一个文件“neighborhoods_mongo.json”导入集合“neighborhoods”。使用相同的函数将第二个文件“restaurants_mongo.json”导入到表“restaurants”中。对于这两种情况,目标集合和表都不存在,因此它们是由 JSON 导入函数自动创建的。


有关 JSON 导入辅助程序的更多详细信息,请参见https://dev.mysql.com/doc/mysql-shell/8.0/en/mysql-shell-utilities-json.html。你也可以直接使用 MySQL Shell 的帮助信息,只需输入:“\h import_json”。

将 JSON 导入集合和表的区别

在使用不同的目标对象(集合或表)时,在导入结果方面存在一些细微的差别。让我们看一下导入数据的结构,看看它们有什么差别。



命令:


> \use test> db.get_collections() > session.sql('SHOW TABLES') > session.sql('SHOW CREATE TABLE test.neighborhoods') > session.sql('SHOW CREATE TABLE test.restaurants')
复制代码


首先,正如预期的那样,我们可以看到“restaurants”数据未被列为集合,因为它是专门导入到表中的。但是,所有导入的文件都列为表,甚至是导入到集合的 JSON 文档。这是因为在内部集合也被存储为 MySQL 表,只是具有非常特定的结构。


再看一下“SHOW CREATE TABLE”命令的输出结果,可以看出它们之间的差别。对于这两种情况,JSON 文档实际上是存储在 JSON 类型的“doc”列中,区别在于标识列。对于“neighborhoods”集合,标识列为“_id”,该列与 JSON 文档中的“_id”字段匹配,该字段包含导入期间转换的 OID。因此,OID 实际上与导入到 MySQL 中的 JSON 文档的 Id 相匹配,作为主键。对于“restaurants”表,标识列为“id”,该列是一个自动增量的整数,为每个 JSON 文档(行)生成一个新的标识。因此,原始 OID 将被忽略,有就是不会作为主键,尽管每个 JSON 文档中的_id 字段将包含导入期间转换的 OID。


在实际当中,这种差异会影响你使用导入数据的方式。如果你选择集合作为导入目标,你就可以使用所有 MySQL 文档存储功能(NoSQL + SQL)。另一方面,如果你选择表作为导入目标,你将只能使用可用的 JSON 类型功能和 MySQL 提供的原生 JSON 函数来操作你的 JSON 数据(仅限 SQL)。

如何为某些导入的数据创建新列

从前面的示例中可以看到,所有导入的数据都存储在 JSON 类型的列中。但是,在某些情况下,可能需要将数据的一部分放在另一列中,例如,创建索引以提升某些查询的执行速度。下面让我们来看一个简单的示例。假设我们将一些额外的 JSON 数据从“primer-dataset.json”导入到新的“my_restaurants”表中,并且我们的应用程序需要查询所有餐馆的名称,以便获取特定类型的菜肴。


命令:


> util.import_json("/path_to_file/primer-dataset.json", {"schema": "test", "table": "my_restaurants"}) > shell.options.outputFormat = "vertical" > session.sql('EXPLAIN SELECT doc->>"$.name" AS name FROM test.my_restaurants WHERE doc->>"$.cuisine" = "Italian"')
复制代码


使用 EXPLAIN 命令查看查询执行计划,我们可以验证查询是否会执行全表扫描,我们不建议使用这种全表扫描的查询方式(特别是对于包含大量数据的表)。幸运的是,我们可以为用于过滤结果的属性添加新列和索引。我们可以使用 ALTER TABLE 语句在生成的列上创建二级索引,从而轻松解决这个问题。


命令:


> session.sql('ALTER TABLE test.my_restaurants ADD COLUMN cuisine VARCHAR(80) GENERATED ALWAYS AS (doc->>"$.cuisine") VIRTUAL, WITH VALIDATION') > session.sql('ALTER TABLE test.my_restaurants ADD INDEX cuisine_idx (cuisine)') > session.sql('EXPLAIN SELECT doc->>"$.name" AS name FROM test.my_restaurants WHERE cuisine = "Italian"')
复制代码


第一个 ALTER TABLE 语句将新列“cuisine”添加到“my_restaurants”表中,它创建了一个虚拟列,并执行了验证,确保生成的值不超出合法范围。然后,执行第二个 ALTER TABLE 语句,在新的“cuisine”列上添加索引。


现在,分析 EXPLAIN 的结果,我们可以验证查询执行成本是否会低得多,因为使用了索引(没有全表扫描)。


注意:在上图中,我们展示了从 MySQL Workbench 获得的查询执行计划的截图,以便更直观地说明每种情况的成本。

动手尝试

MySQL Shell 可从以下链接下载。



可以在此处找到 MySQL Shell 的文档:https://dev.mysql.com/doc/mysql-shell/8.0/en/


以上示例中使用的 JSON 数据可通过以下链接获取。


  • Restaurants 和 NeighborhoodsJSON 文档:


https://raw.githubusercontent.com/mongodb/docs-assets/geospatial/restaurants.json


https://raw.githubusercontent.com/mongodb/docs-assets/geospatial/neighborhoods.json


  • 基础数据集 JSON 文档:


https://raw.githubusercontent.com/mongodb/docs-assets/primer-dataset/primer-dataset.json


英文原文:https://mysqlserverteam.com/importing-data-from-mongodb-to-mysql-using-python/


2018-12-17 00:002246
用户头像

发布了 731 篇内容, 共 433.7 次阅读, 收获喜欢 1997 次。

关注

评论 1 条评论

发布
暂无评论
发现更多内容

Spark 在 KaiwuDB 中的应用与实践

KaiwuDB

数据库 spark

RayLink远程控制软件:叮~你收到一份年度关键词报告

RayLink远程工具

远程控制软件 RayLink

关于接口测试自动化的总结与思考

阿里巴巴云原生

阿里云 云原生 TPS

TiDB 6.5 LTS 发版

PingCAP

#TiDB

软件测试 | 测试开发 | 相比Selenium,Web自动化测试框架Playwright

测吧(北京)科技有限公司

测试

阿里云张献涛:无影,让计算触手可及

云布道师

无影云电脑

Kyligence 客户案例“泰康集团精细化经营分析与运营平台”获评数据智能最佳实践案例

Kyligence

数据分析 指标管理

Seata 1.6.0 正式发布,大幅度提升存储性能

阿里巴巴云原生

阿里云 seata

软件测试/测试开发丨如何确保API 的稳定性与正确性?你只需要这一招

测试人

软件测试 自动化测试 测试开发 RESTful API

Pytorch基础-tensor数据结构

嵌入式视觉

Tensor torch.tensor() Tensor维度

Flutter Hero 动画组件的飞行过程显示控制

岛上码农

flutter ios 安卓 移动端开发 跨平台开发

好家伙!阿里最新SpringBoot进阶笔记涵盖了SpringBoot所有骚操作

程序员小毕

程序员 后端 ssm springboot java面试

性能测试技术笔记(三):如何设计一个压测平台

老张

性能测试 压测平台

Pytorch基础-张量基本操作

嵌入式视觉

张量的基本操作 维度变换 索引切片 合并分割 卷积相关算子

harbor从1.6.1升级至2.7.0

小黄鱼

Harbor

精华推荐 |【深入浅出Sentinel原理及实战】「原理探索专题」完整剖析Alibaba微服务架构体系之轻量级高可用流量控制组件Sentinel(1)

洛神灬殇

sentinel 1月日更 Sentinel 系统

云渲染动画价格一般多少?

Renderbus瑞云渲染农场

云渲染 云渲染价格

WorkPlus平台多业务系统集成,让企业沟通协作更畅通

WorkPlus

高性能存储SIG月度动态:DSMS开始适配Anolis OS、将在ANCK 5.10中支持ublk | 龙蜥 SIG

OpenAnolis小助手

开源 操作系统 高性能存储 龙蜥社区 sig

Bonree ONE荣获信通院“2022IT新治理年度明星产品”

博睿数据

根因分析 博睿数据 荣誉奖项 Bonree ONE

2022 OpenMLDB 硕果累累,颁奖台上荣耀连连

第四范式开发者社区

人工智能 机器学习 数据库 开源 特征

初识PHP(1):PHP是什么

华为云PaaS服务小智

php

卷积神经网络的压缩方法总结

嵌入式视觉

知识蒸馏 模型压缩 神经网络参数量化 二值化网络 模型剪枝

科技创新实力受认可,网易有道入选 2022 中国技术品牌影响力企业榜

有道技术团队

技术 数据分析

InfoQ写作社区 2022 年度优质创作者评选名单公布!

InfoQ写作社区官方

热门活动

企业专用的即时通讯产品如何选择?

WorkPlus

Apipost接口自动化测试功能详解

测试人生路

Postman 自动化测试 接口自动化测试

Apipost——让前端、后端、测试共用一份API文档!

不想敲代码

喜报 | 瑞云科技荣获“第四届天鸽奖十大创新企业”等两项大奖

3DCAT实时渲染

元宇宙 3DCAT 瑞云渲染

2022 InfoQ 写作社区年度优质企业号评选名单公布!

InfoQ写作社区官方

热门活动

同盾科技 x TiDB丨实时数据架构为风控智能决策保驾护航

PingCAP

#TiDB

使用Python将MongoDB数据导到MySQL_语言 & 开发_Paulo Jesus_InfoQ精选文章