一种从 MySQL 迁移数据至 PostgreSQL 的变通方法

1 需求

我自己的电脑上没有安装 MySQL,只有 PostgreSQL,最近我有一个项目要升级,需要合并一部分存在虚拟主机上的 MySQL 中的数据,我希望在不安装 MySQL 的情况下,迁移数据至 PostgreSQL。

2 导入 .sql 文件

我平时用 pgAdmin 管理数据,所以我将 MySQL 的数据下载下来后,打开 pgAdmin 的维护恢复功能,想把 .sql 文件直接导入,结果发现 pgAdmin 不支持通过 .sql 文件恢复。

上网搜索了一下,看到有人说两种数据库转义符之类的都不太一样,导入的时候要配置一些设置,我的数据量比较小,没有细看方法,果断放弃这种方式。

3 通过 .sql 文件的固定格式匹配数据

.sql 文件中全部是 SQL 语句,尤其数据插入部分,非常容易用正则匹配出来。面临的问题只有一个,就是当 .sql 文件比较大时,使用正则表达式可能有点性能问题。于是我想到了下面的办法:

  1. 把我需要的数据表从 .sql 中提取到一个 .txt 文件中,缩小文本量。
  2. 用正则表达式匹配每一条 INSERT 语句。
  3. 用正则表达式分割每一条 INSERT 的字段。
  4. 将得到的数据插入至 PostgreSQL。

3.1 提取数据

提取数据同样有两种办法:

3.1.1 使用 wxMEdit

数据量小可以按此法操作。

如果直接用普通的文本编辑器打开较大的 .sql 文件可能会卡死,要用十六进制模式飞快地打开才行。wxMEdit 可以,而且是开源软件。

Github 上有下载就不多说了,文件打开就是这个样子的:

wxMEdit

选中要复制的数据,粘贴出来就可以。wxMEdit 支持三种模式打开文件: 文本模式列块模式十六进制模式 ,最好先打开 wxMEdit,确认模式无误再打开文件,并且注意打开大文件后不要去点 文本模式 ,会卡死,我有时候控制不住自己。

3.1.2 编写脚本读取

写一个脚本简单匹配一下,一般是从 CREATE 表ALTER 表 ,掐头去尾。不要用 JAVA 或者 C 什么的。Python 等着你呢。

3.2 匹配 INSERT

.sql 文件中的 INSERT 语句形如 (xxx,xxx,'xxx',xxx,'xxx'),(xxx,...),...(xxx,...) 。提取出来先给最后一组数据结尾加个英文逗号,方便正则。

代码很简单。

valuesFileName = 'values.txt'
with open(valuesFileName, 'r') as f:
    rowsPattern = re.compile(r'(?!\\)\(.*?[^\\]\),')
    rows = rowsPattern.findall(f.read())

3.3 分割字段

字段以逗号分隔,但文本类型的字段内可能含有逗号,所以分割的时候不要直接用 str.split(',') ,还是用正则。

# 我的这部分数据只有字符串和数字,所以正则很简单。
# 有 Boolean 数据的的话加个 T 和 F 就好了。
valuesPattern = re.compile(r"(?<='|\d),(?='|\d)"
for row in rows:
    values = valuesPattern.split(row)
    # 下面插入数据

文本类型的字段用 values[i][1:-1] 插入,删掉两头的单引号,其他字段用 values[i]

第一个字段一般是数字类型的 id,用 values[i][1:] 提取以删掉开头的括号,如果是文本就用 values[i][2:-1]

最后一个字段还会在结尾带个逗号,用 values[i][:-2]values[i][1:-3] 提取。

3.4 插入数据

Python 端如果用了 ORM 的话,这一共也就 10 行左右吧。


如何从 MySQL 迁移数据到 PostgreSQL、Python 正则表达式、wxMEdit 的使用方法、用 Python 迁移数据库、用 ORM 的好处、.sql 文件不能导入怎么办。

版权声明:本站所有原创文章,作者保留版权。转载必须包含本声明,不得修改任何内容(包括文章标题),并以超链接的形式注明作者“Bary”和本文原始地址。

发表评论

电子邮件地址不会被公开。 必填项已用*标注