Периодическая ошибка в запросе PostGIS через Rails (ошибка интерполяции строки?) - PullRequest
0 голосов
/ 14 апреля 2020

У меня периодически возникает ошибка после некоторых развертываний моего приложения 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 возвращает: #<RGeo::Geographic::SphericalPointImpl:0x3ffd8b2a6688 "POINT (-72.633932 42.206081)">

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
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]]
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]]
Выполнение преобразования 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 после развертывания. Как будто преобразование строк иногда не работает.

Вот список потенциально важных версий / версий:

  • activerecord-postgis-adapter (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

1 Ответ

1 голос
/ 14 апреля 2020

Нет необходимости преобразовывать географию в строку, а затем считывать ее обратно как географию.

Вы можете попробовать напрямую

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

При этом вы можете действительно имеют некоторые неверные геометрии

...