Typecho 数据从 SQLite3 迁移至 MySQL
Doveccl

工作日大半夜发文……

背景是给服务器额外弄了块云数据盘,并且兴致冲冲格成了 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'
/** @type Promise<sqilte3.Database> */
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()
})()}

顺利收工,睡觉!

 评论
评论插件加载失败
正在加载评论插件
由 Hexo 驱动 & 主题 Keep
总字数 24.2k 访客数 访问量