在上一篇文章中我们已经成功在docker中跑起来了一个sql server。

  现在问题来了,我有一个mdf文件,我应该如何导入到sql server?

  在window平台似乎有对应的工具,但是docker中却不一样。原因是docker相当于创建了一个虚拟的linux环境,在这个环境中运行sql server。作为mac玩家,我们没有类似于window这样的工具。即使有,由于sql server运行在虚拟的环境中,而我们的文件在本地主机中,所以两个是互相隔离的。

  简单来说,如果你想要导入mdf文件,你应该看到有人告诉你这样做:

EXEC  sp_attach_db  @dbname  =  '你的数据库名',     
@filename1  =  'mdf文件路径(包缀名)',     
@filename2  =  'Ldf文件路径(包缀名)'

  但是当你在你的sql server中输入上面的语句,他会告诉你路径不存在。为什么?因为sql server运行在docker提供的虚拟linux上,在那个linux上显然没有你这个文件。

解决方法:

我在https://docs.microsoft.com/zh-cn/sql/linux/sql-server-linux-configure-docker?view=sql-server-2017中找到了解决方案。

简单来说,docker就是一个容器,而我们的数据库文件mdf现在在容器外,我们需要将这个文件放入容器内,才能进行导入。

sql server提供了一种方法叫做:将主机目录加载为数据卷,简单来说就是把我们主机上的一个目录映射到容器内的一个目录上。

然而微软之后又叫了一条提醒,暂时不支持将mac的主机目录加载进去,它提示我们改为使用数据卷。

指令如下:

docker run -e 'ACCEPT_EULA=Y' -e 'MSSQL_SA_PASSWORD=<YourStrong!Passw0rd>' -p 1433:1433 -v sqlvolume:/var/opt/mssql -d mcr.microsoft.com/mssql/server:2017-latest

注意看:这个指令其实是在创建一个sql server 然后这个sql server多了-v sqlvolume:/var/opt/mssql 这一部分, 用于为这个sql server创建一个volume名为sqlvolume,并且这个容器的位置在docker虚拟的linux的/var/opt/mssql中。 如果我们还想为这个数据库命名 我们需要在-p 1433:1433 后面加上一句 --name yourname (如果直接加在最后面会报错)

好了现在我们已经创建了一个带有数据卷的sql server。我们可以使用 docker volume ls 查看是否创建成功,应该会显示一个volume。

类似

DRIVER              VOLUME NAME

local               demovolume

demovolume是我给我的volume取得名字。

 

ok 现在我们只需要将mdf文件拷贝到容器中再导入即可,指令如下:

docker cp <Host path> <Container ID>:<Container path>

container id可以通过 docker ps查看到。

像我这样:

docker cp /yourpath.../DemoHis_log.ldf b2e95c59a4fb:/var/opt/mssql/DemoHis_log.ldf

docker cp /yourpath.../DemoHis.mdf 

 

现在我们在var/opt/mssql/中已经有这两个文件了了只需要在数据库中输入语句

EXEC sp_attach_db @dbname = 'DemoHis',
@filename1 = '/var/opt/mssql/DemoHis.mdf',
@filename2 = '/var/opt/mssql/DemoHis_log.ldf'
GO

就会提示运行成功,至此我们终于将mdf文件导入了docker中的sql server。

 

后记:

虽然写的很多很杂,但是还是要写,一方面自己没有太多时间去写的很好看,但是另外一方面这个问题在网上又没有找到别的解决方法。网上的博客中都是泛泛而谈,装环境的博客千千万,装完环境之后能不能用倒是没人关心了。hello world之后的第二步,也是需要开拓的。

mac 下使用sql server的坑实在多,为了导入一个mdf文件就要这样费神,只能留下一篇这样的流水记,勉励探索的后人。