
本文介绍在 linux 环境(尤其是 docker 容器化场景)中,使用 `mssql-scripter` 和 `sqlcmd` 实现 sql server 数据库的自动化导出(含结构与数据)与导入,完美替代 postgresql 中 `pg_dump`/`psql` 的工作流。
在基于 Docker 的 PHP 自动化测试环境中,频繁重置数据库至基线状态是刚需。不同于 PostgreSQL 生态成熟的 pg_dump/psql,SQL Server 在 Linux 下原生缺乏开箱即用的 CLI 导出/导入工具。但通过微软官方维护的 mssql-scripter(基于 Python 的跨平台脚本生成器)配合 sqlcmd(轻量级命令行执行器),可构建稳定、可复现的自动化数据快照流水线。
✅ 核心工具链说明
| 工具 | 用途 | 类比 |
|---|---|---|
| mssql-scripter | 生成包含 DDL(表/索引/约束)和 DML(INSERT)的 .sql 脚本 | ≈ pg_dump –clean –schema-and-data |
| sqlcmd | 执行 SQL 脚本文件或单条语句 | ≈ psql -f dump.sql |
⚠️ 注意:mssql-scripter 不直接执行恢复操作,它只生成可执行的 T-SQL 脚本;实际导入必须由 sqlcmd 或其他 SQL Server 客户端完成。
? 推荐 Docker 构建方案(适配现代 OpenSSL 与编码)
由于上游 mssql-scripter 存在已知兼容性问题(如 Issue #236),需手动集成新版 sqltoolsservice 并修复 UTF 编码缺陷。以下为生产就绪的多阶段精简版 Dockerfile 片段:
FROM ubuntu:22.04
# 安装依赖与 SQL Server 工具链
RUN apt-get update && apt-get install -y /
curl wget gnupg unzip libunwind8 /
&& curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add - /
&& curl https://packages.microsoft.com/config/ubuntu/$(lsb_release -rs)/prod.list > /etc/apt/sources.list.d/msprod.list /
&& apt-get update /
&& apt-get install -y msodbcsql18 mssql-tools18 /
&& echo 'export PATH="$PATH:/opt/mssql-tools18/bin"' >> ~/.bashrc
# 安装 Python 3.9+ 与 mssql-scripter
RUN apt-get install -y python3-pip python3-dev /
&& pip3 install --no-cache-dir mssql-scripter==1.0.0a15
# 替换 sqltoolsservice(关键!解决 OpenSSL 3.x 兼容性)
ARG SQLTOOLS_URL=https://github.com/microsoft/sqltoolsservice/releases/download/v3.0.0-release.205/Microsoft.SqlTools.ServiceLayer-rhel-x64-net6.0.tar.gz
RUN mkdir -p /opt/Microsoft.SqlTools.ServiceLayer /
&& curl -sSL $SQLTOOLS_URL | tar -xzf - -C /opt/Microsoft.SqlTools.ServiceLayer --strip-components=1
# 修复 UTF-8 编码 bug(强制使用 UTF-16 输出,避免 BOM/乱码)
RUN sed -i 's/utf-8/utf-16/g' /usr/local/lib/python3.*/dist-packages/mssqlscripter/main.py
ENV MSSQLTOOLSSERVICE_PATH=/opt/Microsoft.SqlTools.ServiceLayer
ENV LANG=C.UTF-8
# 验证安装
RUN mssql-scripter --help >/dev/null && sqlcmd -? >/dev/null || exit 1
✅ 构建后,容器内即可执行标准化命令:
# 导出全量结构 + 数据(含 DROP + CREATE + INSERT) mssql-scripter -S mssql-host -d mydb -U sa -P 'MyPass!123' / --schema-and-data / --exclude-object-type Login,User,Role,ServerRoleMembership / --target-server-version SQLServer2019 / > dump.sql # 导入(注意:目标库需已存在,且用户有 db_owner 权限) /opt/mssql-tools18/bin/sqlcmd -S mssql-host -d mydb -U sa -P 'MyPass!123' -i dump.sql
? 关键注意事项与最佳实践
- 权限要求:mssql-scripter 需要 db_owner 或 VIEW DEFINITION + SELECT 权限;sqlcmd 导入需 db_ddladmin + db_datawriter。
- 字符集安全:务必使用 –encoding utf-16(或通过上述 patch 强制)避免中文/特殊字符乱码;生成脚本建议用 iconv -f UTF-16 -t UTF-8 dump.sql 转换后再检查。
- 排除对象:测试环境应显式 –exclude-object-type Login,User,避免跨环境 SID 冲突。
- 事务控制:sqlcmd 默认不开启事务,若需原子性恢复,可在 dump.sql 开头添加 BEGIN TRY BEGIN TRANSACTION … COMMIT END TRY BEGIN CATCH ROLLBACK; THROW; END CATCH 包裹逻辑(需自行注入)。
-
替代方案参考:
- 若仅需数据迁移(非结构重建),可用 bcp(更高效,但无 schema 导出能力);
- 若接受容器内运行 PowerShell,Invoke-SqlCmd + Export-SqlData 是 Windows 方案,但不符合纯 Linux 要求;
- PHP 项目中也可直接调用 exec() 封装上述命令,无需额外语言栈。
通过该方案,你将获得与 pg_dump/psql 行为高度一致、可 CI/CD 集成、完全容器化的 SQL Server 数据快照能力——让每一次浏览器自动化测试,都从干净、可预测的数据库状态开始。
