SQLCipher数据迁移到PostgreSql详细攻略

步骤一、安装Docker

  • Windows11 安装Docker客户端教程:自己百度一下。

步骤二、SQLCipher解密,转换为Sqlite3

  • 访问官网进行下载
  • 使用DB Browser (SQLCipher) 客户访问数据库文件后,点开菜单栏 "工具" --> "设置加密",密码置空后,即可进行解密,自动将SQLCipher转换为Sqlite3。
  • 注意:这个解密的过程耗时比较长,请耐心等待;

步骤三、将Sqlite中的数据迁移到PostgreSql中

1. Docker安装PostgreSql

bash 复制代码
docker run --name my_postgres \
  -e POSTGRES_PASSWORD=mysecretpassword \  # 设置超级用户密码,务必修改
  -p 5432:5432 \                           # 映射主机端口 5432 到容器端口 5432
  -v pgdata:/var/lib/postgresql/data \     # 使用命名卷 pgdata 持久化数据
  -d \                                     # 后台运行容器
  postgres                                 # 使用官方镜像
  • -e POSTGRES_PASSWORD=mysecretpassword: 务必修改 mysecretpassword为你自己设定的强密码,这是默认的超级用户 postgres的密码。
  • -v pgdata:/var/lib/postgresql/data: 这里的 pgdata是 Docker 管理的命名卷(Named Volume)​ 的名称。如果该卷不存在,Docker 会自动创建它。数据会存储在 Docker 的管理区域(例如 /var/lib/docker/volumes/),与容器生命周期分离,从而实现持久化。
  • 使用 docker volume ls可以查看所有已创建的命名卷。
  • 增加 --restart=unless-stopped 可以自动启动容器,除非手动停止。

2. 拉取pgloader镜像

bash 复制代码
docker pull ghcr.io/dimitri/pgloader:latest

3. 准备迁移脚本 migration.load

bash 复制代码
LOAD DATABASE
    FROM sqlite:////data/main_data.db
    INTO postgresql://postgres:123456@host.docker.internal:5432/main

WITH include drop, create tables, create indexes, reset sequences, foreign keys,
     workers = 8, concurrency = 1

ALTER SCHEMA 'main' RENAME TO 'public'

BEFORE LOAD DO
$$ create schema if not exists public; $$;

🔔 参数说明​:

  • FROM: SQLite 源数据库连接字符串。这里使用了 sqlite:///前缀,后接文件路径。请注意,即使SQLite数据库有密码(你连接字符串中的Password=E32CE1F29B6745F984DA86FBC0159F9F),​pgloader对SQLite的支持目前可能不直接支持通过连接字符串传递密码 。你可能需要先使用SQLite工具解密数据库或寻找其他方法(如临时移除密码)再进行迁移。/是路径分隔符,D:/NewData/main_data.db是你的数据库文件路径。

  • INTO: PostgreSQL 目标数据库连接字符串。格式为 postgresql://username:password@host:port/database_name

  • WITH 子句:

    • include drop: 迁移前删除目标数据库中已存在的同名表(⚠️谨慎使用,会清除现有数据!​ 如果 scan_spec数据库是新创建的或可清空,则使用此选项;若需保留现有数据,请移除此选项)。
    • create tables: 在PostgreSQL中创建表。
    • create indexes: 创建索引。
    • reset sequences: 重置序列(例如自增主键的序列)。
    • foreign keys: 创建外键约束。
    • workers = 8: 使用8个工作线程加速迁移(可根据CPU核心数调整)。
    • concurrency = 1: 控制并发度。
  • ALTER SCHEMA: SQLite 没有模式概念,其表通常可视为在 main模式中。此命令在迁移后将模式名改为 PostgreSQL 默认的 public

  • BEFORE LOAD DO: 迁移前执行的 SQL 语句,这里确保 public模式存在。

4. 执行迁移

使用 Docker 运行 pgloader并执行迁移脚本。​注意将 /path/to/your/migration.load 替换为你实际的 migration.load文件的绝对路径。/path/to/your/data 替换为你实际的 db 文件的所在目录。

bash 复制代码
docker run --rm -v /path/to/your/migration.load:/migration.load -v /path/to/your/data:/data ghcr.io/dimitri/pgloader:latest pgloader /migration.load

🔔 命令说明​:

  • --rm: 容器退出后自动删除。

  • -v /path/to/your/migration.load:/migration.load: 将宿主机上的加载脚本挂载到容器内。

  • -v /path/to/your/data:/data: 将包含你 SQLite 数据库文件的目录挂载到容器内的 /data目录,确保容器内的 pgloader 能访问到 /path/to/your/data/main_data.db 文件(因此在.load文件中,路径可以写为 sqlite:////data/main_data.db,但上述脚本已使用宿主机绝对路径,此挂载是为了保证一致性)。

  • ghcr.io/dimitri/pgloader:latest: pgloader 的 Docker 镜像。

  • pgloader /migration.load: 在容器内运行的命令,执行迁移脚本。

步骤四、特别注意

由于 Pgloader 在将 SQLite 的 INTEGER 类型(在 SQLite 中通常用来表示布尔值,0 或 1)迁移到 PostgreSQL 时,将它映射成了 PostgreSQL 的 BIT 类型,而不是 BOOLEANINTEGER。PostgreSQL 的 BIT 类型是位字符串类型,它和 INTEGER 类型无法直接进行 = 比较。所以当你执行 "isdelete" = 0 时,PostgreSQL 就会报错,提示找不到一个可以比较 BITINTEGER 的操作符。报错信息如下:

复制代码
SQL 错误 [42883]: ERROR: operator does not exist: bit = integer
Hint: No operator matches the given name and argument types. You might need to add explicit type casts.

所以我们需要将数据库中所有bit(1)类型的字段转换成boolean类型,但是PostgreSql中这两个类型不能直接转换,所以要先将bit(1)先转成 integer 再转成 boolean。下面是一个可以完成这个任务的 PostgreSQL PL/pgSQL 代码块。你可以将其作为一个匿名代码块 (DO 语句) 在 psql 或任何 PostgreSQL 客户端中运行。

SQL 复制代码
DO $$

DECLARE
rec RECORD;
table_name TEXT;
column_name TEXT;
alter_sql TEXT;

BEGIN

-- 遍历数据库中所有表的模式(public)
FOR rec IN
SELECT
c.table_schema,
c.table_name,
c.column_name
FROM
information_schema.columns c
WHERE
c.table_schema = 'public' -- 只在 public 模式下查找,可以根据需要更改
AND c.data_type = 'bit'
AND c.character_maximum_length = 1
LOOP
table_name := rec.table_name;
column_name := rec.column_name;
RAISE NOTICE '正在处理表: %, 列: %', table_name, column_name;

-- 构造 ALTER TABLE 语句,先转成 integer
alter_sql := format('ALTER TABLE %I.%I ALTER COLUMN %I TYPE INTEGER USING %I::integer;',
rec.table_schema, table_name, column_name, column_name);

-- 执行 SQL
EXECUTE alter_sql;

-- 构造 ALTER TABLE 语句,再转成 boolean
alter_sql := format('ALTER TABLE %I.%I ALTER COLUMN %I TYPE BOOLEAN USING %I::boolean;',
rec.table_schema, table_name, column_name, column_name);

-- 执行 SQL
EXECUTE alter_sql;
END LOOP;
RAISE NOTICE '所有 bit(1) 字段转换完成。';
END $$;

到此,SQLite的数据已经全部迁移到PostgreSql啦~

相关推荐
IvorySQL1 天前
PostgreSQL 全表 count 优化实践:从 SeqScan 痛点分析到 heapam 改进与性能突破
数据库·postgresql·oracle·deepseek·ivorysql
IvorySQL8 天前
IvorySQL 4.6:DocumentDB+FerretDB 实现 MongoDB 兼容部署指南
postgresql
l1t8 天前
利用DeepSeek实现服务器客户端模式的DuckDB原型
服务器·c语言·数据库·人工智能·postgresql·协议·duckdb
小兜全糖(xdqt)9 天前
pyspark 从postgresql读取数据
数据库·postgresql
心随_风动9 天前
Ubuntu 文件复制大师:精通cp命令完整指南
数据库·ubuntu·postgresql
IvorySQL9 天前
PostgreSQL 上的向量搜索实践
postgresql·llm
J.Kuchiki9 天前
【PostgreSQL内核学习:表达式】
数据库·postgresql