SQL ServerをPodmanコンテナで動かすときにCSVをBulk Insertで読み込む方法
SQL Serverで大量のCSVデータを取り込む場合、BULK INSERTを使うと高速にデータを登録できます。
しかし、SQL ServerをPodmanなどのコンテナ上で動かしている場合、
「ホスト側にあるCSVファイルを、SQL Serverコンテナからどうやって読み込ませるのか?」
という問題があります。
本記事では、Podmanの-vオプションを利用してホスト側のディレクトリをSQL Serverコンテナにマウントし、BULK INSERTでCSVを読み込む方法を紹介します。
1. SQL ServerでCSVを読み込む
大量のCSVファイルをSQL Serverへ取り込む場合、BULK INSERTを利用できます。
例えば、以下のようなCSVファイルがあるとします。
001,山田太郎,40
002,佐藤花子,35
003,鈴木一郎,50
これをSQL Serverのテーブルへ取り込む場合、通常は次のように記述します。
BULK INSERT dbo.Person
FROM 'C:\mydata\person.csv'
WITH (
FORMAT = 'CSV',
FIELDQUOTE = '"',
FIELDTERMINATOR = ',',
ROWTERMINATOR = '\n'
);
大量のデータを扱う場合、1件ずつINSERTするよりもBULK INSERTを利用した方が効率的です。
2. SQL Serverをコンテナで動かす場合の問題
SQL ServerをPodmanコンテナで動かしている場合でも、BULK INSERT自体は利用できます。
しかし、ここで問題になるのがCSVファイルの場所です。
例えばホストOS上に、
/home/user/data/person.csv
というCSVファイルが存在していたとしても、SQL Serverコンテナから見ると、そのファイルは必ずしも存在しているわけではありません。
コンテナはホストOSとは独立したファイルシステムを持っているためです。
そのため、
BULK INSERT dbo.Person
FROM '/home/user/data/person.csv'
としても、SQL Serverコンテナ内にそのファイルが存在しなければ読み込むことができません。
そこで、Podmanのボリュームマウントを利用します。
3. Podmanの-vでホストのディレクトリをコンテナにマウントする
Podmanには、ホストOSのディレクトリをコンテナ内のディレクトリとして利用するための-vオプションがあります。
基本的な形式は、
-v ホスト側ディレクトリ:コンテナ側ディレクトリ
です。
例えば、ホスト側の
/home/user/sqlserver-data
を、SQL Serverコンテナの
/var/opt/mssql/backups
として利用する場合は、次のようにします。
podman run \
-e ACCEPT_EULA=Y \
-e MSSQL_SA_PASSWORD='YourPassword' \
-p 1433:1433 \
-v /home/user/sqlserver-data:/var/opt/mssql/backups \
mcr.microsoft.com/mssql/server:2025-latest
これで、ホスト側の
/home/user/sqlserver-data
にあるファイルを、コンテナ内から
/var/opt/mssql/backups
として参照できます。
例えばホスト側に、
/home/user/sqlserver-data/person.csv
を配置すると、コンテナ内のSQL Serverからは、
/var/opt/mssql/backups/person.csv
として見えるようになります。
4. CSVを配置してBULK INSERTする
コンテナを起動した状態で、ホスト側のマウント元ディレクトリにCSVファイルを配置します。
/home/user/sqlserver-data/
└── person.csv
すると、コンテナ内では、
/var/opt/mssql/backups/
└── person.csv
としてアクセスできます。
あとはSQL ServerからBULK INSERTを実行します。
BULK INSERT dbo.Person
FROM '/var/opt/mssql/backups/person.csv'
WITH (
FORMAT = 'CSV',
FIELDQUOTE = '"',
FIELDTERMINATOR = ',',
ROWTERMINATOR = '0x0a'
);
これで、ホスト側に置いたCSVをSQL Serverコンテナから直接読み込むことができます。
ポイントは、
BULK INSERTで指定するファイルパスは「ホスト側のパス」ではなく「SQL Serverコンテナから見えるパス」にする
ということです。
ディレクトリ構成のイメージ
全体としては、次のような関係になります。
ホストOS
/home/user/sqlserver-data/
│
│ Podman -v
↓
SQL Serverコンテナ
/var/opt/mssql/backups/
│
↓
person.csv
│
↓
BULK INSERT
│
↓
SQL Serverのテーブル
5. ROWTERMINATORには0x0aの形で指定する
CSVを読み込む際に、行末の指定で少し注意が必要です。
Windows環境では
ROWTERMINATOR = '\n'
などの表記をしますが、Linux環境では、
ROWTERMINATOR = '0x0a'
と指定します。
6. CODEPAGEについて
もう一つ注意したいのがCODEPAGEです。
Windows環境では、
CODEPAGE = '65001'
のような指定をしたくなるかもしれません。
しかし、Linux環境ではCODEPAGEが指定できません。
なので、対象のCSVはutf-8である必要があります。
7. まとめ
SQL ServerをPodmanコンテナで動かしている場合でも、BULK INSERTを使って大量のCSVデータを取り込むことができます。
ポイントは、SQL ServerコンテナからCSVファイルが見えるようにすることです。
今回の方法では、Podmanの-vオプションを使って、
ホスト側
/home/user/sqlserver-data
を、
コンテナ側
/var/opt/mssql/backups
としてマウントします。
その上で、ホスト側にCSVを配置し、SQL Serverから、
BULK INSERT dbo.Person
FROM '/var/opt/mssql/backups/person.csv'
WITH (
FORMAT = 'CSV',
FIELDTERMINATOR = ',',
ROWTERMINATOR = '0x0a'
);
のように実行します。
つまり、
- SQL Serverでは大量のCSV取り込みに
BULK INSERTを利用する - SQL ServerコンテナからホストのCSVはそのままでは見えない
- Podmanの
-vでホストのディレクトリをコンテナにマウントする - マウントしたディレクトリにCSVを配置する
- コンテナから見えるパスを
BULK INSERTに指定する -
ROWTERMINATOR = '0x0a'を使用する - 今回の方法では
CODEPAGEは指定しない
という流れになります。
コンテナ環境でも、ファイルをコンテナへコピーするのではなく、ホストのディレクトリをSQL Serverのファイル置き場としてマウントしてしまうことで、比較的シンプルにBULK INSERTを利用できます。