在 Linux (Kubuntu) 上从 MySQL 迁移到 PostgreSQL
很久以前,在一个很远很远的系统上...
尝试将数据库从 MySQL 迁移到 PostgreSQL。我读过的所有文档都非常详细地介绍了如何迁移结构。我发现有关迁移数据的文档很少。该架构有 13 个表(已成功迁移)和 9 GB 数据。
MySQL版本:5.1.x
PostgreSQL版本:8.4.x
我想使用R编程语言使用SQL select语句来分析数据; PostgreSQL 有 PL/R,但 MySQL 没有(据我所知)。
新希望
创建数据库位置(/var
空间不足;也不喜欢到处都有 PostgreSQL 版本号——升级会破坏脚本!):
sudo mkdir -p /home/postgres/ main
sudo cp -Rp /var/lib/postgresql/8.4/main /home/postgres
sudo chown -R postgres.postgres /home/postgres
sudo chmod -R 700 /home/postgres
sudo usermod -d /home/postgres/ postgres
一切顺利。接下来,重新启动服务器并使用以下安装说明配置数据库:
sudo apt-get安装postgresql pgadmin3
sudo /etc/init.d/postgresql-8.4 stop
sudo vi /etc/postgresql/8.4/main/postgresql.conf
- 更改
data_directory
到/home/postgres/main
sudo /etc/init.d/postgresql-8.4 start
sudo -u postgres psql postgres
code>\password postgres
sudo -u postgres createdb Climate
pgadmin3
使用 pgadmin3
配置数据库并创建模式。
这一事件在一个名为 bash
的远程 shell 中继续,两个数据库都在运行,并且安装了一组带有相当不寻常徽标的工具:SQL 仙女.
perl Makefile.PL
sudo make install
sudo apt-get install perl-doc
(奇怪的是,它不叫perldoc
>)perldoc SQL::Translator::Manual
提取 PostgreSQL 友好的 DDL 和所有 MySQL
数据:
sqlt -f DBI --dsn dbi:mysql:气候 --db-user 用户 --db-password 密码 -t PostgreSQL > Climate-pg-ddl.sql
- 编辑
climate-pg-ddl.sql
并将标识符转换为小写,然后插入模式引用(使用 VIM)::%s/"\([A-Z_]*\)"/\L\1/g
:%s/表/表气候./g
:%s/关于/关于气候。/g
mysqldump --skip-add-locks --complete-insert --no-create-db --no-create-info --quick --result-file="climate-my.sql" --databases Climate --skip-comments -u root -p
将 MySQL 中的表和列重命名为小写可能是值得的:
select concat( 'RENAME TABLE Climate.', TABLE_NAME, ' to Climate.', lower(TABLE_NAME), ';' ) from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA='climate';
- 从上一步。
- 可能有一种方法可以对列执行相同的操作;我手动更改它们,因为它比弄清楚如何编写查询更快。
数据库反击
在 PostgreSQL 中重新创建结构,如下所示:
pgadmin3
(切换到它)- 单击执行任意 SQL 查询图标
- 打开
climate-pg-ddl.sql
- 搜索
TABLE“
替换为TABLE Climate.”
(插入架构名称climate
) - 在“< /code> 替换为
on Climate."
(插入模式名称climate
) - 按
F5
执行
这会导致:
Query returned successfully with no result in 122 ms.
Replies of the Jedi
At这一点我很困惑。
- 我应该从这里去哪里(步骤是什么)将
climate-my.sql
转换为climate-pg.sql
以便他们可以针对 PostgreSQL 执行? - 如何确保正确复制索引(以保持引用完整性;目前没有限制来简化转换)?
- 如何确保在 PostgreSQL 中添加新行将从插入的最后一行的索引开始枚举(并且不与序列中的现有主键冲突)?
- 将数据从 MySQL 转换为 PostgreSQL 插入时,如何确保模式名称能够通过?
资源
需要相当多的信息才能达到此目的:
- https://help.ubuntu.com/community/ PostgreSQL
- http://articles.sitepoint.com/article/site- mysql-postgresql-1
- http://wiki.postgresql.org/wiki/Converting_from_other_Databases_to_PostgreSQL# MySQL
- http://pgfoundry.org/frs/shownotes.php?release_id= 810
- http://sqlfairy.sourceforge.net/
谢谢!
A long time ago on a system far, far away...
Trying to migrate a database from MySQL to PostgreSQL. All the documentation I have read covers, in great detail, how to migrate the structure. I have found very little documentation on migrating the data. The schema has 13 tables (which have been migrated successfully) and 9 GB of data.
MySQL version: 5.1.x
PostgreSQL version: 8.4.x
I want to use the R programming language to analyze the data using SQL select statements; PostgreSQL has PL/R, but MySQL has nothing (as far as I can tell).
A New Hope
Create the database location (/var
has insufficient space; also dislike having the PostgreSQL version number everywhere -- upgrading would break scripts!):
sudo mkdir -p /home/postgres/main
sudo cp -Rp /var/lib/postgresql/8.4/main /home/postgres
sudo chown -R postgres.postgres /home/postgres
sudo chmod -R 700 /home/postgres
sudo usermod -d /home/postgres/ postgres
All good to here. Next, restart the server and configure the database using these installation instructions:
sudo apt-get install postgresql pgadmin3
sudo /etc/init.d/postgresql-8.4 stop
sudo vi /etc/postgresql/8.4/main/postgresql.conf
- Change
data_directory
to/home/postgres/main
sudo /etc/init.d/postgresql-8.4 start
sudo -u postgres psql postgres
\password postgres
sudo -u postgres createdb climate
pgadmin3
Use pgadmin3
to configure the database and create a schema.
The episode continues in a remote shell known as bash
, with both databases running, and the installation of a set of tools with a rather unusual logo: SQL Fairy.
perl Makefile.PL
sudo make install
sudo apt-get install perl-doc
(strangely, it is not calledperldoc
)perldoc SQL::Translator::Manual
Extract a PostgreSQL-friendly DDL and all the MySQL
data:
sqlt -f DBI --dsn dbi:mysql:climate --db-user user --db-password password -t PostgreSQL > climate-pg-ddl.sql
- Edit
climate-pg-ddl.sql
and convert the identifiers to lowercase, and insert the schema reference (using VIM)::%s/"\([A-Z_]*\)"/\L\1/g
:%s/ TABLE / TABLE climate./g
:%s/ on / on climate./g
mysqldump --skip-add-locks --complete-insert --no-create-db --no-create-info --quick --result-file="climate-my.sql" --databases climate --skip-comments -u root -p
It might be worthwhile to simply rename the tables and columns in MySQL to lowercase:
select concat( 'RENAME TABLE climate.', TABLE_NAME, ' to climate.', lower(TABLE_NAME), ';' ) from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA='climate';
- Execute the commands from the previous step.
- There is probably a way to do the same for columns; I changed them manually because it was faster than figuring out how to write the query.
The Database Strikes Back
Recreate the structure in PostgreSQL as follows:
pgadmin3
(switch to it)- Click the Execute arbitrary SQL queries icon
- Open
climate-pg-ddl.sql
- Search for
TABLE "
replace withTABLE climate."
(insert the schema nameclimate
) - Search for
on "
replace withon climate."
(insert the schema nameclimate
) - Press
F5
to execute
This results in:
Query returned successfully with no result in 122 ms.
Replies of the Jedi
At this point I am stumped.
- Where do I go from here (what are the steps) to convert
climate-my.sql
toclimate-pg.sql
so that they can be executed against PostgreSQL? - How to I make sure the indexes are copied over correctly (to maintain referential integrity; I don't have constraints at the moment to ease the transition)?
- How do I ensure that adding new rows in PostgreSQL will start enumerating from the index of the last row inserted (and not conflict with an existing primary key from the sequence)?
- How do you ensure the schema name comes through when transforming the data from MySQL to PostgreSQL inserts?
Resources
A fair bit of information was needed to get this far:
- https://help.ubuntu.com/community/PostgreSQL
- http://articles.sitepoint.com/article/site-mysql-postgresql-1
- http://wiki.postgresql.org/wiki/Converting_from_other_Databases_to_PostgreSQL#MySQL
- http://pgfoundry.org/frs/shownotes.php?release_id=810
- http://sqlfairy.sourceforge.net/
Thank you!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我通常为此类迁移做两件事:
然后进行转换,并用您最熟悉的任何语言编写一个程序来完成以下任务:
重新设计 PostgreSQL 的表以利用其功能。
如果您只是使用
sed
脚本将 SQL 转储从一种格式转换为另一种格式,那么您只需执行以下操作:我们正在做的是将 MySQL 数据库放入 PostgreSQL 服务器中。您可以这样做,而且这样做仍然会有一些好处,但如果您要迁移,请完全迁移。这将需要花费更多的前期时间,但我还没有遇到过不值得的情况。
What I usually do for such migrations is two-fold:
Then do the conversion, and write a program in whatever language you are most comfortable with that accomplishes the following:
Redesign the tables for PostgreSQL to take advantage of its features.
If you just do something like use a
sed
script to convert the SQL dump from one format to the next, all you are doing is putting a MySQL database in a PostgreSQL server. You can do that, and there will still be some benefit from doing so, but if you're going to migrate, migrate fully.It will involve a little bit more up-front time spent, but I have yet to come across a situation where it isn't worth it.
将 mysqldump 文件转换为 PostgreSQL 友好的格式
按如下方式转换数据(不要使用 mysql2pgsql.perl):
转义引号。
sed "s/\\\'/\'\'/g" Climate-my.sql | sed "s/\\\r/\r/g" | sed sed "s/\\\n/\n/g" > escaped-my.sql
将
USE "climate";
替换为搜索路径并注释注释:sed "s/USE \"climate\";/SET search_path TO Climate;/g" escaped-my.sql | sed "s/^\/\*/--/" > climate-pg.sql
连接到数据库。
sudo su - postgres
psql Climate
设置编码(mysqldump忽略其编码参数),然后执行脚本。
\编码 iso-8859-1
\i Climate-pg.sql
这一系列步骤可能不适用于具有多种混合类型的复杂数据库。但是,它适用于整数、varchar 和浮点型。
索引、主键和序列
由于
mysqldump
在生成INSERT
语句时包含主键,因此它们将胜过表的自动序列。经检查,所有表的序列仍为 1。导入后设置序列
使用 ALTER SEQUENCE 命令将它们设置为所需的任何值。
架构前缀
无需为表添加架构名称前缀。使用:
Convert the mysqldump file to a PostgreSQL-friendly format
Convert the data as follows (do not use mysql2pgsql.perl):
Escape the quotes.
sed "s/\\\'/\'\'/g" climate-my.sql | sed "s/\\\r/\r/g" | sed "s/\\\n/\n/g" > escaped-my.sql
Replace the
USE "climate";
with a search path and comment the comments:sed "s/USE \"climate\";/SET search_path TO climate;/g" escaped-my.sql | sed "s/^\/\*/--/" > climate-pg.sql
Connect to the database.
sudo su - postgres
psql climate
Set the encoding (mysqldump ignores its encoding parameter) and then execute the script.
\encoding iso-8859-1
\i climate-pg.sql
This series of steps will probably not work for complex databases with many mixed types. However, it works for
integer
s,varchar
s, andfloat
s.Indexes, primary keys, and sequences
Since
mysqldump
included the primary keys when generating theINSERT
statements, they will trump the table's automatic sequence. The sequences for all tables remained 1 upon inspection.Set the sequence after import
Using the
ALTER SEQUENCE
command will set them to whatever value is needed.Schema Prefix
There is no need to prefix tables with the schema name. Use:
如果您已经转换了架构,那么迁移数据将是简单的部分:
从 PostgreSQL 转储架构(您说过您已将架构转换为 postgres,所以我们现在将转储它,因为我们将删除并重新创建目标数据库,将其清理):
将模式拆分为2 部分 —
/tmp/dbname-schema-1.sql
包含创建表语句,/tmp/dbname-schema-2.sql
— 其余部分。 PostgreSQL 需要在导入外键、触发器等之前导入数据,但在导入表定义之后。仅使用架构的 1 部分重新创建数据库:
导入数据:
<前>(
echo '开始交易';
mysqldump --skip-quote-names 数据库名 | grep ^插入;
回显'提交'
)| psql 数据库名
-- 现在我们有包含数据的表,但没有触发器、外键等。
MySQL 5.1.3 中添加了
--skip-quote-names
选项,因此如果您有旧版本,请暂时在/tmp/mysql
(configure --prefix=/tmp/mysql && make install
应该做)并使用/tmp/mysql/bin/mysqldump
。导入架构的其余部分:
If you've converted a schema then migrating data would be the easy part:
dump schema from PostgreSQL (you said that you've converted schema to postgres, so we will dump it for now, as we will be deleting and recreating target database, to have it cleaned):
split schema to 2 parts —
/tmp/dbname-schema-1.sql
containing create table statements,/tmp/dbname-schema-2.sql
— the rest. PostgreSQL needs to import data before foreign keys, triggers etc. are imported, but after table definitions are imported.recreate database with only 1 part of schema:
import data:
A
--skip-quote-names
option is added in MySQL 5.1.3, so if you have older version, then install newer mysql temporarily in/tmp/mysql
(configure --prefix=/tmp/mysql && make install
should do) and use/tmp/mysql/bin/mysqldump
.import the rest of schema:
查看 etlalchemy。它允许您用 4 行 Python 代码从 MySQL 迁移到 PostgreSQL,或者在几个其他数据库之间迁移。您可以在此处了解更多相关信息。
安装:
pip install etlalchemy
运行:
Check out etlalchemy. It allows you migrate from MySQL to PostgreSQL, or between several other databases, in 4 lines of Python. You can read more about it here.
To install:
pip install etlalchemy
To run: