PostgreSQL to MySQL
PostgreSQLもまだまだ現役ですが、フロントエンジニアからすれば、ツールの充実などの都合でMySQLを選択せざるを得ない状況も増えてきました。PHPもまだまだ現役。なんとか一発でMySQLへの移行ができたらと思い、作りました。
'your_postgresql_host', // PostgreSQLのホスト
'db' => 'your_postgresql_dbname', // 使用するデータベース名
'user' => 'your_postgresql_user', // ユーザー名
'password' => 'your_postgresql_password' // パスワード
];
// MySQLデータベースの設定を配列に保存します
$mysql = [
'host' => 'your_mysql_host', // MySQLのホスト
'db' => 'your_mysql_dbname', // 使用するデータベース名
'user' => 'your_mysql_user', // ユーザー名
'password' => 'your_mysql_password' // パスワード
];
// PostgreSQLデータベースにPDOを使用して接続します
$pgsqlConn = new PDO("pgsql:host={$pgsql['host']};dbname={$pgsql['db']}", $pgsql['user'], $pgsql['password']);
// publicスキーマ内の全てのテーブル名を取得するSQLクエリを実行します
$tablesResult = $pgsqlConn->query("SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'");
$tables = $tablesResult->fetchAll(PDO::FETCH_COLUMN); // 結果を配列として取得
// 取得したテーブルごとに処理を行います
foreach ($tables as $table) {
// MySQLデータベースにPDOを使用して接続します
$mysqlConn = new PDO("mysql:host={$mysql['host']};dbname={$mysql['db']}", $mysql['user'], $mysql['password']);
// 対象テーブルのカラム名とデータ型を取得します
$columnsResult = $pgsqlConn->query("SELECT column_name, data_type FROM information_schema.columns WHERE table_name = '{$table}'");
$columns = $columnsResult->fetchAll(PDO::FETCH_ASSOC);
// MySQLで使用するCREATE TABLE文を組み立てます
$createTableSQL = "CREATE TABLE `{$table}` (";
$colDefinitions = [];
// 取得したカラムごとに処理を行います
foreach ($columns as $column) {
$colName = $column['column_name']; // カラム名
$dataType = $column['data_type']; // データ型
// PostgreSQLのデータ型をMySQLのデータ型に変換します
switch ($dataType) {
case 'character varying':
case 'text':
$mysqlDataType = 'TEXT';
break;
case 'integer':
$mysqlDataType = 'INT';
break;
case 'timestamp without time zone':
$mysqlDataType = 'TIMESTAMP';
break;
case 'date':
$mysqlDataType = 'DATE';
break;
default:
$mysqlDataType = 'TEXT'; // デフォルトではTEXT型を使用
}
$colDefinitions[] = "`$colName` $mysqlDataType"; // カラム定義を配列に追加
}
$createTableSQL .= join(', ', $colDefinitions) . ");"; // CREATE TABLE文を完成させます
$mysqlConn->exec($createTableSQL); // MySQLでテーブルを作成
// PostgreSQLからデータを選択し、MySQLに挿入します
$pgsqlResult = $pgsqlConn->query("SELECT * FROM \"{$table}\"");
while ($row = $pgsqlResult->fetch(PDO::FETCH_ASSOC)) {
// カラム名を取得
$columns = array_keys($row);
// 値のプレースホルダーを生成
$placeholders = array_fill(0, count($row), '?');
// INSERT文を組み立て
$insertSQL = "INSERT INTO `{$table}` (`" . implode('`, `', $columns) . "`) VALUES (" . implode(', ', $placeholders) . ")";
// MySQLデータベースへのトランザクションを開始します
$mysqlConn->beginTransaction();
try {
// INSERT文を準備し、値をバインドして実行します
$stmt = $mysqlConn->prepare($insertSQL);
$stmt->execute(array_values($row)); // PDOStatement::executeには値の配列を渡します
$mysqlConn->commit(); // 変更をコミットし、トランザクションを終了します
} catch (Exception $e) {
// エラーが発生した場合、トランザクションをロールバックします
$mysqlConn->rollBack();
echo "エラー: " . $e->getMessage();
}
}
}
?>
文字コードに気をつけて
カラム名に日本語を使ってる場合や、EUCからUTF8に移行する場合などは下記のmysqlへの接続部分を改変してください。じゃないと化けます。
$mysqlConn = new PDO("mysql:host={$mysql['host']};dbname={$mysql['db']};charset=utf8mb4", $mysql['user'], $mysql['password']);