【问题标题】:Intermittent error in PostGIS query via Rails (string interpolation failure?)通过 Rails 查询 PostGIS 时出现间歇性错误(字符串插值失败?)
【发布时间】:2020-04-14 00:12:36
【问题描述】:

一些部署我的 Rails 应用程序后出现间歇性错误。

此代码在 Sidekiq 中运行(5 个进程,每个进程有 10 个线程),它在 Docker 容器中运行。 我可以随时将数以万计的此类作业排队。

path = Path.find(path_id)
nearby_nodes = Node.where("ST_DWITHIN(geog, ST_GeographyFromText(?), 25)", path.geog.to_s)

错误是:

ActiveRecord::StatementInvalid: PG::InternalError: ERROR: parse error - invalid geometry
HINT: "01" <-- parse error at position 2 within geometry
PG::InternalError: ERROR: parse error - invalid geometry
HINT: "01" <-- parse error at position 2 within geometry

如果我让所有 Sidekiq 进程安静下来,停止工作人员,稍等片刻,然后重新启动工作人员,我可以让这些作业成功运行。

我在部署过程中添加了一些延迟(猜测如果重新启动工作人员可以解决问题,那么放慢速度可能会有所帮助),但这并没有帮助。

我通常可以每天​​成功部署一次。在第一次部署之后,它更有可能陷入这种失败状态,如果它进入这种状态,那么之后的每次部署都会导致同样的问题。

Path.first.geog 返回: #&lt;RGeo::Geographic::SphericalPointImpl:0x3ffd8b2a6688 "POINT (-72.633932 42.206081)"&gt;

Path.first.geog.class 返回: RGeo::Geographic::SphericalPointImpl

我尝试了许多不同格式的此查询,这可能有助于了解失败的原因/原因(尽管我仍然不知道为什么它只是间歇性的):

  1. Node.where("ST_DWITHIN(geog, ST_GeographyFromText(?), 25)", path.geog) 失败,生成此查询:
Node Load (1.0ms)  SELECT "nodes".* FROM "nodes" WHERE (ST_DWITHIN(geog, ST_GeographyFromText('0020000001000010e6c05228925785f8d340451a60dcb9a9da'), 25)) LIMIT $1  [["LIMIT", 11]]

这个错误:

ActiveRecord::StatementInvalid (PG::InternalError: ERROR:  parse error - invalid geometry)
HINT:  "00" <-- parse error at position 2 within geometry
  1. Node.where("ST_DWITHIN(geog, ST_GeographyFromText('#{path.geog}'), 25)") 成功,生成此查询:
Node Load (5.1ms)  SELECT "nodes".* FROM "nodes" WHERE (ST_DWITHIN(geog, ST_GeographyFromText('POINT (-72.633932 42.206081)'), 25)) LIMIT $1  [["LIMIT", 11]]
  1. Node.where("ST_DWITHIN(geog, ST_GeographyFromText(?), 25)", path.geog.to_s) 也成功,生成相同的查询:
Node Load (2.3ms)  SELECT "nodes".* FROM "nodes" WHERE (ST_DWITHIN(geog, ST_GeographyFromText('POINT (-72.633932 42.206081)'), 25)) LIMIT $1  [["LIMIT", 11]]
  1. 在前一行中进行 to_s 转换作为某种迷信测试也有效:
geog_string  = path.geog.to_s
nearby_nodes = Node.where("ST_DWITHIN(geog, ST_GeographyFromText(?), 25)", geog_string)

查询 2-4 通常可以工作,但在某些时候仅在部署后表现得像查询 1。 我无法让 2-4 表现得像 Rails 控制台中的第一个查询。 唯一一次查询 2-4 表现得像第一个查询是在部署后的 Sidekiq 作业中。 好像字符串转换有时不起作用。

以下是可能相关的 gem/版本的列表:

  • activerecord-postgis-适配器 (6.0.0)
  • pg (1.2.3)
  • 导轨 (6.0.2.2)
  • rgeo (2.1.1)
  • rgeo-activerecord (6.2.1)
  • sidekiq (6.0.6)
  • Ruby 2.6.6
  • PostgreSQL 11.6
  • PostGIS 2.5.2
  • Docker 19.03.8,构建 afacb8b7f0

【问题讨论】:

    标签: ruby-on-rails postgresql docker postgis sidekiq


    【解决方案1】:

    无需将地理转换为字符串,然后将其作为地理读回。

    你可以直接试试

    Node.where("ST_DWITHIN(geog, ?, 25)", path.geog)
    

    话虽如此,您可能确实有一些无效的几何图形

    【讨论】:

    • 我认为无效的几何图形会导致查询总是失败。但是,重新启动服务允许这些查询成功完成。我现在也很困惑为什么我认为我需要ST_GeographyFromText - 如果没有它,这个查询也可以工作。
    猜你喜欢
    • 1970-01-01
    • 2016-08-30
    • 1970-01-01
    • 1970-01-01
    • 2022-01-19
    • 2018-02-08
    • 1970-01-01
    • 2021-05-16
    • 1970-01-01
    相关资源
    最近更新 更多