Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 35cda6e91c | |||
| ba00e7ecf6 | |||
| e3a1be1844 | |||
| fd279b6c8b |
@@ -309,9 +309,16 @@ class EntityImporter
|
|||||||
return $newId;
|
return $newId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @var array<string, string[]> Cache of existing columns per table */
|
||||||
|
private array $tableColumnsCache = [];
|
||||||
|
|
||||||
|
/** @var array<string, string[]> Skipped columns log per entity type */
|
||||||
|
private array $skippedColumnsLog = [];
|
||||||
|
|
||||||
private function insertWithRawSql(string $entityType, array $record, string $newId): void
|
private function insertWithRawSql(string $entityType, array $record, string $newId): void
|
||||||
{
|
{
|
||||||
$tableName = $this->camelCaseToUnderscore($entityType);
|
$tableName = $this->camelCaseToUnderscore($entityType);
|
||||||
|
$existingColumns = $this->getTableColumns($tableName);
|
||||||
|
|
||||||
// Convert camelCase fields to snake_case for SQL
|
// Convert camelCase fields to snake_case for SQL
|
||||||
$columns = [];
|
$columns = [];
|
||||||
@@ -325,15 +332,27 @@ class EntityImporter
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip non-storable array/object fields that come from getValueMap
|
$column = $this->camelCaseToUnderscore($field);
|
||||||
if (is_array($value) || is_object($value)) {
|
|
||||||
// JSON fields should be stored as JSON strings
|
// Skip columns that don't exist in the target table
|
||||||
if (is_array($value) || is_object($value)) {
|
if (!in_array($column, $existingColumns)) {
|
||||||
$value = json_encode($value, JSON_UNESCAPED_UNICODE);
|
if (!isset($this->skippedColumnsLog[$entityType][$column])) {
|
||||||
|
$this->skippedColumnsLog[$entityType][$column] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// JSON fields should be stored as JSON strings
|
||||||
|
if (is_array($value) || is_object($value)) {
|
||||||
|
$value = json_encode($value, JSON_UNESCAPED_UNICODE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fix empty strings for integer/bool columns (MySQL strict mode)
|
||||||
|
if ($value === '' || $value === false) {
|
||||||
|
$value = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$column = $this->camelCaseToUnderscore($field);
|
|
||||||
$columns[] = "`{$column}`";
|
$columns[] = "`{$column}`";
|
||||||
$values[] = $value;
|
$values[] = $value;
|
||||||
$placeholders[] = '?';
|
$placeholders[] = '?';
|
||||||
@@ -344,14 +363,42 @@ class EntityImporter
|
|||||||
|
|
||||||
$sql = "INSERT INTO `{$tableName}` ({$columnStr}) VALUES ({$placeholderStr})";
|
$sql = "INSERT INTO `{$tableName}` ({$columnStr}) VALUES ({$placeholderStr})";
|
||||||
|
|
||||||
try {
|
$pdo = $this->entityManager->getPDO();
|
||||||
$pdo = $this->entityManager->getPDO();
|
$stmt = $pdo->prepare($sql);
|
||||||
$stmt = $pdo->prepare($sql);
|
$stmt->execute($values);
|
||||||
$stmt->execute($values);
|
}
|
||||||
} catch (\Exception $e) {
|
|
||||||
// If column mismatch, try with just known columns
|
private function getTableColumns(string $tableName): array
|
||||||
throw $e;
|
{
|
||||||
|
if (isset($this->tableColumnsCache[$tableName])) {
|
||||||
|
return $this->tableColumnsCache[$tableName];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$pdo = $this->entityManager->getPDO();
|
||||||
|
$sth = $pdo->query("SHOW COLUMNS FROM `{$tableName}`");
|
||||||
|
$columns = [];
|
||||||
|
|
||||||
|
while ($row = $sth->fetch(\PDO::FETCH_ASSOC)) {
|
||||||
|
$columns[] = $row['Field'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->tableColumnsCache[$tableName] = $columns;
|
||||||
|
|
||||||
|
return $columns;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string, string[]> entityType => [skipped column names]
|
||||||
|
*/
|
||||||
|
public function getSkippedColumns(): array
|
||||||
|
{
|
||||||
|
$result = [];
|
||||||
|
|
||||||
|
foreach ($this->skippedColumnsLog as $entityType => $columns) {
|
||||||
|
$result[$entityType] = array_keys($columns);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function resetAutoIncrement(string $entityType): void
|
private function resetAutoIncrement(string $entityType): void
|
||||||
|
|||||||
@@ -179,6 +179,18 @@ class ImportService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Report skipped columns (missing in target DB)
|
||||||
|
$skippedColumns = $this->entityImporter->getSkippedColumns();
|
||||||
|
|
||||||
|
if (!empty($skippedColumns)) {
|
||||||
|
$io->writeLine('');
|
||||||
|
$io->writeLine('WARNING: Skipped columns not found in target database:');
|
||||||
|
|
||||||
|
foreach ($skippedColumns as $type => $columns) {
|
||||||
|
$io->writeLine(" {$type}: " . implode(', ', $columns));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function entityTypeExists(string $entityType): bool
|
private function entityTypeExists(string $entityType): bool
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "DataMigration",
|
"name": "DataMigration",
|
||||||
"version": "1.2.1",
|
"version": "1.2.3",
|
||||||
"acceptableVersions": [
|
"acceptableVersions": [
|
||||||
">=8.0.0"
|
">=8.0.0"
|
||||||
],
|
],
|
||||||
|
|||||||
Reference in New Issue
Block a user