工作日大半夜发文……
背景是给服务器额外弄了块云数据盘,并且兴致冲冲格成了 XFS,于是就想装个 PostgreSQL 玩玩,顺便就想把一些项目原本放在 SQLite3 中的数据迁移到正规的数据库
本来下班前已经完成了 SQLite3 到 PostgreSQL 的迁移,但是发现博客里有些插件会在 sql 里写 int(10)
这种东西,然后在只认 integer
的 PostgreSQL 上就光荣挂掉了(其实主要影响了可以忽略不计的阅读量统计,以及评论发表,虽然也没啥评论)
想一想还是用 MySQL 吧。于是上手五年没碰过的 MySQL,上来就遇到 MySQL8 默认鉴权方式的坑,最后在 Google 的帮助下才把 root@localhost 的鉴权改成了老的方式让 php 能用
然后新的问题又出现了,SQLite3 生成的 dump 文件里表名、字段名都是双引号 "
,但是 MySQL 里只认 `
不认 "
,本来想写一个正则替换了事结果发现事情并没有那么简单:可能还是误改到了 values 里面的一些东西,反正最后直接是 php 报错了
索性就写个脚本逐条拷贝算了(需要先运行 install.php 生成表结构):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| const util = require('util') const mysql = require('mysql') const sqilte3 = require('sqlite3')
const dbpath = '/data/www/blog/usr/blog.db'
const linkSqlite = new Promise((res, rej) => { const db = new sqilte3.Database(dbpath, err => { err ? rej(err) : res(db) }) })
const con = mysql.createConnection({ user: 'root', database: 'typecho', })
const query = util.promisify(con.query.bind(con)) const connect = util.promisify(con.connect.bind(con))
{(async () => { await connect() const lite = await linkSqlite const all = util.promisify(lite.all.bind(lite)) const tbs = await query('show tables') for (const tb of tbs) { const table = Object.values(tb)[0] await query(`delete from ${table}`) const cols = await query(`show columns from ${table}`) const keys = cols.map(x => x.Field) const datas = await all(`select * from ${table}`) let cnt = 0 for (const data of datas) { cnt++ const sql = mysql.format( `insert into \`${table}\` (${ keys.map(k => `\`${k}\``).join(',') }) values (${ keys.map(() => '?').join(',') })`, keys.map(k => data[k]) ) await query(sql) } console.log('insert to', table, 'count', cnt) } con.destroy() })()}
|
顺利收工,睡觉!