以前のFileMakerからMySQLへのMigrationの続きになる(もう2年も経つのか)。オブジェクトの移行例としてBase64への変換方法を記載した。
実際この方法でMySQLのlongtextに取り込んでみたが、既存のオブジェクトとBase64分で容量が2.5倍くらいになってしまう。FileMakerのデータの9割近くをオブジェクトが占めており、ただでさえサーバーのディスクを圧迫してプログレッシブバックアップもままらなくなっている状況でこれを採用するのは厳しい。MySQL側もDB内にオブジェクトデータを持つと肥大化し後々データの取り回しに困るだろう。
そこで、オブジェクトは外部に保存してMySQLにはリンクだけ持たせることにした。保存先はAWS S3を採用。セキュアに保つためにはいくつか方法があるが、取り敢えずMySQLにはファイル名だけ持って都度S3の署名付きURLを発行することにした(S3の署名付きURLについてはネットにいっぱい情報があるのでそちらを参考にしてください)。
手順は以下(Mac用)。
- FileMakerからオブジェクトをエクスポート(出力するファイル名はGetContainerAttribute ( image ; "filename" ) などで取得)
- シェルスクリプトなどでエクスポートしたファイルをS3にアップロード
cronで1のFileMakerスクリプトと2のシェルスクリプトを5分毎とかに実行する
cronで呼び出すスクリプト
#!/bin/sh
date
open 'fmp://<アカウント名>:<パスワード>@<FileMaker ServerホストのIPアドレス>/<FileMakerファイル名>.fmp12?script=Export updated data since last run for MySQL'
FileMakerスクリプトから呼び出すスクリプト
#!/bin/bash
date
cd /Users/<ユーザ名>/Documents/<一時CSV保存先のフォルダ名>/
file1=*.csv
sftp -i /Users/iwaninc/.ssh/dbserver.cer -oPort="<sftpポート番号>" <DBサーバのユーザ名>@<DBサーバのIPアドレス> << END
cd temp/csv/
mput $file1
quit
END
cronで呼び出すスクリプト
#!/bin/bash
# cronで実行に必要
PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
export PATH
# ログファイルのパス
LOG_FILE="/Users/<ユーザ名>/Documents/tmp/upload_script.log"
echo "$(date) Start..." >> "$LOG_FILE"
# アップロード先のS3バケット名
S3_BUCKET="<S3バケット名>"
# アップロード先のS3オブジェクトプレフィックス
S3_PREFIX="<S3オブジェクトプレフィックス>"
# アップロードするファイルのあるローカルディレクトリ
TMP_DIRECTORY="/Users/<ユーザ名>/Documents/<一時画像保存先のフォルダ名>"
# オブジェクトファイルをアップロード
find "$TMP_DIRECTORY" -type f -print0 | while IFS= read -r -d $'\0' file; do
if aws s3 cp "$file" "s3://$S3_BUCKET/$S3_PREFIX/$(basename "$file")"; then
echo "$(date) Uploaded: $file" >> "$LOG_FILE"
rm "$file"
else
echo "$(date) Upload failed: $file" >> "$LOG_FILE"
fi
done
echo "$(date) Upload and deletion completed." >> "$LOG_FILE"
以上だが、FileMakerのオブジェクトフィールドは外部保存にしており、最初サーバーの外部保存ファイルをS3にアップしていた。
しかし、それだとFileMakerで取得するファイル名と外部保存されているファイルの名前が一致しないもの(拡張子の大文字が小文字になってたりheicやjpegがjpgになってたり)が出てきて問題だったのでオブジェクトフィールドをエクスポートする方法に変更した。エクスポートしたファイルの容量が問題になりそうだが上記をcronで5分毎とかに実行しているのでほとんど問題にならない。
ニーズがあるかどうかわからないがやったことの記録として上げときます。