原则问题:无法从您发送到 GEOMETRY 字段的数据中获取几何对象

Posted

技术标签:

【中文标题】原则问题:无法从您发送到 GEOMETRY 字段的数据中获取几何对象【英文标题】:Doctrine issue: Cannot get geometry object from data you send to the GEOMETRY field 【发布时间】:2019-05-22 15:30:37 【问题描述】:

我跟着this guide把point类型加到Doctrine里了。

这就是我在实体中定义坐标字段的方式:

/**
 * @ORM\Column(type="point", nullable=true)
 */
private $coordinates;

这就是我试图保存实体的方式:

$obj = new GeoPoint();
$obj->setAddress('Test');
$obj->setCoordinates(new Point(40.7603807, -73.9766831));
$manager->persist($obj);
$manager->flush();

我的配置:

doctrine:
    dbal:
        types:
            point: Viny\PointType
        driver: 'pdo_mysql'
        server_version: '5.7'
        charset: utf8mb4
        default_table_options:
            charset: utf8mb4
            collate: utf8mb4_unicode_ci
        url: '%env(resolve:DATABASE_URL)%'
        mapping_types:
            point: point
    orm:
        auto_generate_proxy_classes: '%kernel.debug%'
        naming_strategy: doctrine.orm.naming_strategy.underscore
        quote_strategy: backend_lib.orm.quote_strategy
        auto_mapping: true
        mappings:
            App:
                is_bundle: false
                type: annotation
                dir: '%kernel.project_dir%/src/Entity'
                prefix: 'App\Entity'
                alias: App

结果数据库列定义:

`coordinates` point DEFAULT NULL,

结果我得到:

使用参数 ["Test", "POINT(-73.976683 40.760381)"] 执行 'INSERT INTO geo_point (address, coordinates) VALUES (?, ?)' 时发生异常:

SQLSTATE[22003]:数值超出范围:1416 无法获取几何 对象来自您发送到 GEOMETRY 字段的数据

最终查询:

插入geo_pointaddresscoordinates)值('测试','POINT(-73.976683 40.760381)');

【问题讨论】:

将转储语句添加到 PointType::convertToDatabaseValue 并验证是否正在生成类似于 POINT(40.7603807, -73.9766831) 的内容。这将显示接线是否正确。有点奇怪,new Point() 并没有因为缺少构造函数参数而发出警告,而是离题。 我很确定你想在你的配置文件中使用类型:point: App\...\PointType。否则,我看不到 Doctrine 将如何知道使用您的自定义 PointType。 symfony.com/doc/current/reference/configuration/… 我已经用 INSERT 语句更新了错误信息。另外,PointType::convertToDatabaseValue() 的输出是string(27) "POINT(-73.976683 40.760381)"(坐标之间没有逗号) 【参考方案1】:

您发布的doctrine configuration 是错误的。应该是:

#doctrine.yaml
doctrine:
    dbal:
        types: ### Use types instead of mapping_types
            point: App\...\GeoPointType

您可以判断出映射是因为您生成的 sql 的问题:

INSERT INTO geo_point (address, coordinates) VALUES ('Test', 'POINT(-73.976683 40.760381)');

mysql本身不理解POINT。它需要包装在 PointFromText 中。这种包装是通过以下方式完成的:

    // class GeoPointType
    public function convertToDatabaseValueSQL($sqlExpr, AbstractPlatform $platform)
    
        return sprintf('PointFromText(%s)', $sqlExpr);
    

而且它显然没有被调用。

Here is a working example.

【讨论】:

感谢您的提示,您的回答可能是正确的,但对我而言并非如此。因为,这个错误的一个实际原因是我的自定义 QuoteStrategy::getColumnName() 调用添加了引号:return $this->quote($class->fieldMappings[$fieldName]['columnName'], $platform); 如果禁用此策略,则 SQL 是正确的:GeomFromText(?) 好吧。我没有做任何自定义引用,但我确实尝试了您的 mapping_types 配置,我得到的只是一个 DBAL 异常:“要覆盖的类型点不存在。”我怀疑您可能安装了其他一些学说包或其他东西。就这样。 我已经切换到CrEOF/doctrine2-spatial,所以我的配置已经正确并且发生了类似的问题。这是文件:gist.github.com/lngphp/a6e9a5de1287604ad4ffb9d25c1abcb2 这就是它的启用方式:gist.github.com/lngphp/3857a8c3000a9789c596ab250874cd1f

以上是关于原则问题:无法从您发送到 GEOMETRY 字段的数据中获取几何对象的主要内容,如果未能解决你的问题,请参考以下文章

mysqldump 无法从您发送到已添加的 GEOMETRY 字段的数据中获取几何对象 --hex-blob

将查询结果插入 mysql 中的列时,无法从发送到 GEOMETRY 字段的数据中获取几何对象

从工作台向 MySQL 8.0 中插入一个点

从您的应用程序向 Google Play 商店发送费率

Spring Boot(MVC)下空间字段(Geometry)与geojson的自动转换

oracle怎么处理,A表的ST_GEOMETRY类型插入到B表的ST_GEOMETRY类型,怎么做?