LoginSignup
6
8

More than 3 years have passed since last update.

Docker内にSQL Serverを立ててPythonでアクセスする

Last updated at Posted at 2019-09-30

はじめに

とあるご縁でちょっとしたデータ分析の仕事をやらせて頂いているのですが、今回SQLを触ることになり、先方から頂いたデータは.bakファイル(Mirosoft SQL独自のバックアップ形式)でした。これを復元してMacOSで環境構築するまでにかなり手こずり、情報も散乱・錯綜している気がしたので、ここに一連の流れをメモとしてまとめたいと思います。

環境

PC: MacBook Air (Retina, 13-inch, 2018)
OS: macOS Mojave
メモリ: 16GB

SQL Serverを立てる

まず.bakファイルをインポートしようと調べると、Azure Data Studio(旧 SQL Operations Studio )というGUIでrestoreできるっぽい。そこで公式ページに飛ぶと、Microsoft SQLはMacOSでは使えない! でも大丈夫、代わりにDockerイメージを公式が配布していて、この中にSQL Serverを立てて使えということらしいです。

具体的な手順としては、以下に従っていけばOKです。
Quickstart: Run SQL Server container images with Docker
How to Restore a SQL Server Database on a Mac using SQL Operations Studio

Docker Desktopを入れる

公式からdmgファイルをダウンロードして実行します。Docker Hubへの会員登録が必要です。

インストールが完了したら、Docker Desktopを立ち上げて以下のようにDocker Desktop is runningと表示が出ていればOKです。(画像は公式より)

スクリーンショット 2019-05-30 1.59.59.png

コンテナを立てる

ここら辺は以下の記事を参考にしました。
Dockerを使用してMacからSQL Serverに接続する(方法編)
Linux Docker コンテナーでの SQL Server データベースを復元します。

SQL Serverコンテナイメージをpull

sudo docker pull mcr.microsoft.com/mssql/server:2017-latest

以下のコマンドで、コンテナイメージにパスワードを設定して実行することができます。usernameはデフォルトでsaになります。

docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=<YourStrong!Passw0rd>' \
   -p 1433:1433 \
   -d mcr.microsoft.com/mssql/server:2017-latest

docker psで以下のような出力が得られたら大丈夫です。

$ docker ps
CONTAINER ID        IMAGE                          COMMAND                  CREATED             STATUS              PORTS                    NAMES
bbcf81bcad49        microsoft/mssql-server-linux   "/opt/mssql/bin/sqls…"   9 days ago          Up 15 hours         0.0.0.0:1433->1433/tcp   sql1

次はローカルにある.bakファイルをイメージ内にコピーしましょう。
ここではコンテナ名がsql1であるとします。

sudo docker exec -it sql1 mkdir /var/opt/mssql/backup
sudo docker cp PATH_TO_BAK_FILE sql1:/var/opt/mssql/backup

これでコンテナが起動している状態でSQL Serverにアクセスすることができます。

もしPCを再起動するなどしてコンテナが止まってしまった場合、

docker ps -a #container idを確認
docker restart <container id>

でコンテナをリスタートすることができます。

Azure Data Studioを入れる

公式からインストール。

インストールが終了したら、必要な情報を入力して、コンテナに接続します。

スクリーンショット 2019-05-31 14.41.55.png

restoreから進んで、コンテナ内の.bakファイルへのパスを指定します。

tmp.png

スクリーンショット 2019-05-31 17.01.29.png

上手くいけば、左のSERVERSのカラムにrestoreしたDBが追加されます! Visual Studioライクでなかなか良さげ。

Pythonでアクセスする

次はPythonでテーブルにアクセスしたいので、pyodbcを導入します。他のライブラリとしてpymysqlも試したのですが、自分の場合はうまく行きませんでした...

具体的な手順としては、Microsoft公式の以下がかなり分かりやすいです。
Create Python apps using SQL Server on macOS

# Homebrewのインストール
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
# Pythonが入っていなければ入れる
brew install python

# ODBCドライバ・SQLサーバー用コマンドラインツールのインストール
brew tap microsoft/mssql-release https://github.com/Microsoft/homebrew-mssql-release
brew update
brew install msodbcsql17 mssql-tools

# pyodbcのインストール
pip3 install pyodbc

接続を確認するプログラムとして、簡単なプログラムを書いて実行します。

Connect.py
import pyodbc

server = '127.0.0.1'
database = 'DB_NAME' #データベース名
username = 'sa'
password = 'PASSWORD' #サーバーに設定したパスワード

cnxn = pyodbc.connect(
'DRIVER={ODBC Driver 17 for SQL Server};SERVER='+server+';DATABASE='+database+';UID='+username+';PWD='+ password
)
cursor = cnxn.cursor()

rows = cursor.execute('select * from sys.objects;').fetchall()
cnxn.close()
print(rows)

ここのserverの値についてですが、server='localhost'としていると名前解決がうまくいかない場合があるみたいなので、ホスト名でなくIPアドレスで指定しておくと良いみたいです(自分も動かなくなりました)。

Jupyter Notebookで触る

やっぱりJupyter Notebook上でPandasとか使いたいですよね...? でも、notebook上で読み込もうとするとエラーが出る場合があります。その場合は、ターミナルとJupyter notebook上で以下のコマンドの出力を確認してみてください。

!odbcinst -j

unixODBC 2.3.7
DRIVERS............: /etc/odbcinst.ini
SYSTEM DATA SOURCES: /etc/odbc.ini
FILE DATA SOURCES..: /etc/ODBCDataSources
USER DATA SOURCES..: /Users/ricky/.odbc.ini
SQLULEN Size.......: 8
SQLLEN Size........: 8
SQLSETPOSIROW Size.: 8

パスが違っていたらとりあえずそれがエラーの原因なので、愚直にコピーします。root権限が必要なのでJupyter上ではなくターミナルからsudoで実行しましょう。シンボリックリンクを貼っても良いと思います。

これで、jupyter notebookからもテーブルにアクセスできるようになりました!

6
8
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
8