KTV/app/Console/Commands/TransferSqliteToMysql.php

81 lines
2.6 KiB
PHP

<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Config;
class TransferSqliteToMysql extends Command
{
protected $signature = 'transfer:sqlite-to-mysql';
protected $description = 'Transfer all data from SQLite to MySQL, optionally truncating tables first.';
public function handle(): int
{
// ✅ 自訂 SQLite 連線路徑(請修改為你實際的檔案位置)
Config::set('database.connections.sqlite', [
'driver' => 'sqlite',
'database' => base_path('database/database.sqlite'),
'prefix' => '',
]);
$this->info("🚀 Starting transfer from SQLite to MySQL...");
// 讀取 SQLite 資料庫的所有資料表
$sqliteTables = DB::connection('sqlite')->select("
SELECT name FROM sqlite_master
WHERE type='table' AND name NOT LIKE 'sqlite_%';
");
if (empty($sqliteTables)) {
$this->error("❌ No tables found in SQLite database.");
return 1;
}
// 取得 .env 中指定的 MySQL 連線名稱
$mysqlConnection = config('database.default'); // 默認會是 'mysql',如果 .env 修改會自動更新
foreach ($sqliteTables as $tableObj) {
$table = $tableObj->name;
// 忽略 Laravel 內部 migration 表
if ($table === 'migrations') {
continue;
}
$this->info("📦 Transferring table: {$table}");
try {
// 用 cursor 來避免一次性佔用過多記憶體
$rows = DB::connection('sqlite')->table($table)->cursor();
$buffer = [];
$count = 0;
foreach ($rows as $row) {
$buffer[] = (array) $row;
$count++;
if ($count % 500 === 0) {
DB::connection($mysqlConnection)->table($table)->insert($buffer);
$buffer = []; // 清空 buffer
}
}
// 插入剩下的資料
if (!empty($buffer)) {
DB::connection($mysqlConnection)->table($table)->insert($buffer);
}
$this->info("✅ Done: {$table} ({$count} records)");
} catch (\Exception $e) {
$this->error("❌ Failed to transfer {$table}: " . $e->getMessage());
}
}
$this->info("🎉 Transfer complete!");
return 0;
}
}