Symfony中Doctrine自定义PostGIS类型引发迁移类型变更错误
问题解决思路
问题根源
你遇到的错误是因为自定义PointType继承的GeometryType默认生成geometry(GEOMETRY, 0)类型的字段,但实际我们需要的是geometry(POINT, 0)。Doctrine对比实体映射和数据库结构时,误判为需要修改空间列类型,而PostGIS禁止修改空间列的基础类型,因此抛出错误。
解决步骤
1. 修正自定义PointType的SQL声明逻辑
重写父类的几何类型和SRID方法,让Doctrine生成正确的POINT类型字段:
use Jsor\Doctrine\PostGIS\Types\GeometryType; class PointType extends GeometryType { public const POINT = 'point_type'; // 指定几何类型为POINT protected function getGeometryType(): string { return 'POINT'; } // 指定SRID,根据业务需求修改(比如常用的4326) protected function getSrid(): int { return 0; } // 保留你原有的转换方法 public function convertToPHPValue($value, AbstractPlatform $platform): ?Point { if ($value === null) { return null; } $pattern = '/POINT\(([-]?[0-9]+[.]?[0-9]*) ([-]?[0-9]+[.]?[0-9]*)\)/'; if (preg_match($pattern, $value, $matches)) { $latitude = (float) $matches[1]; $longitude = (float) $matches[2]; return new Point($latitude, $longitude); } else { throw new \DomainException('Incorrect string'); } } public function convertToDatabaseValue($value, AbstractPlatform $platform): ?string { /** @var Point $value */ if ($value === null) { return null; } return sprintf('POINT(%f %f)', $value->getLatitude(), $value->getLongitude()); } public function requiresSQLCommentHint(AbstractPlatform $platform): bool { return true; } }
2. 修复现有数据库字段类型
PostGIS不允许直接修改空间列的基础类型,需要手动创建迁移修正字段:
// 手动生成的迁移文件 public function up(Schema $schema): void { // 保留数据的修改方式(优先使用) $this->addSql('ALTER TABLE parking ALTER COLUMN center_location TYPE geometry(POINT, 0) USING ST_Transform(center_location, 0)'); // 无数据或可重新导入数据时,可使用删除重建: // $this->addSql('ALTER TABLE parking DROP COLUMN center_location'); // $this->addSql('ALTER TABLE parking ADD center_location geometry(POINT, 0) DEFAULT NULL'); } public function down(Schema $schema): void { $this->addSql('ALTER TABLE parking ALTER COLUMN center_location TYPE geometry(GEOMETRY, 0) USING ST_Transform(center_location, 0)'); }
3. 验证Doctrine类型映射
确保config/packages/doctrine.yaml中的类型配置正确:
doctrine: dbal: types: point_type: App\Entity\PropertyType\PointType polygon_type: App\Entity\PropertyType\PolygonType mapping_types: geometry: point_type
4. 清除Doctrine缓存
避免旧的类型映射残留:
php bin/console doctrine:cache:clear-metadata php bin/console doctrine:cache:clear-query
5. 测试迁移生成
现在重新生成迁移,不会再出现类型变更错误:
php bin/console doctrine:migrations:diff
内容的提问来源于stack exchange,提问作者carameil5
相关产品推荐
相关产品推荐

