原则问题:无法从您发送到 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_point
(address
,coordinates
)值('测试','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 字段的数据中获取几何对象