rgeo / activerecord-postgis-adapter

ActiveRecord connection adapter for PostGIS, based on postgresql and rgeo
Other
865 stars 232 forks source link

Polygon issues with table dump in schema, loading in migrations #371

Closed jathayde closed 2 years ago

jathayde commented 2 years ago

This seems to be in the same vein of #61 but pretty far removed in the scheme of time from that issue report.

Ran into this trying to run db:test:prepare and started walking through it manually, finding it choked on db:schema:load when it tried to create an index pointing to the points_of_interest table, which it had not created. Looking at schema.rb, I see the following line:

# Could not dump table "points_of_interest" because of following StandardError
#   Unknown type 'geometry(Polygon)' for column 'boundary_area'

The POI migration has two lines related to geometry:

      t.st_polygon :boundary_area
      t.st_point :lonlat, geographic: true

If I run db:migrate in the test environment instead, I end up with a similar issue, failing on st_polygon but for a different model (events), with the same migration lines. The actual error is a massive stack dump, which starts with:

undefined method `st_polygon' for #<ActiveRecord::ConnectionAdapters::PostgreSQL::TableDefinition:0x000000010eb36ca8 [...]

The full dump is here: https://gist.github.com/jathayde/5e30ce50c741cbcd2ffe24cb6f47dad6

These occur after the postgis extension is enabled in an earlier migration.

I have not reset the development database, and am avoiding doing so right now as to continue to be able to work.

ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-darwin21] Rails 7.0.3.1 activerecord_postgis_adapter 8.0.1 Postgresql 13

active_record_extended gem is installed (other issues seem to relate to AR extension gems that might conflict, so adding that as a note in case that's a sure culprit)

keithdoggett commented 2 years ago

Hi @jathayde thanks for providing a lot of details with the issue.

I created a new rails app based on the setup you provided and wasn't able to replicate the issue. I also tried install the active_record_extended gem to see if that was causing it, but I was still able to prepare the db and load the schema fine.

It seems like the ColumnMethods module was not properly included in the Postgres::Table class (see: https://github.com/rgeo/activerecord-postgis-adapter/blob/master/lib/active_record/connection_adapters/postgis/column_methods.rb). Can you try running this in the rails console to ensure that it's properly included?

ActiveRecord::ConnectionAdapters::PostgreSQL::Table.include?(ActiveRecord::ConnectionAdapters::PostGIS::ColumnMethods)

Is it possible you have some other Gem installed that is also modifying the ActiveRecord Postgresql adapter?

jathayde commented 2 years ago

Thanks @keithdoggett !

That console request returns true in both rails c and RAILS_ENV=test rails c

I don't see anything else that would jump out at me as a culprit, but here's the gem file: https://gist.github.com/jathayde/e98de97a32ff2ac025f2837da0cff8d4

I did run bundle:update and tried db:schema:dump, and any table with a st_polygon throws the geometry(Polygon) unknown error.

I'm not sure if it's related, but with some recent update, the schema annotation at the top of the file changed for the geospatial items:

Screen Shot 2022-08-25 at 1 43 36 PM

I also tried to change this gem to run off the current master branch (~24 days old) and db:schema:dump returns this in terminal:

❯ bin/rails db:schema:dump
D, [2022-08-25T13:46:47.772662 #79219] DEBUG -- : using default configuration
unknown OID 175407: failed to recognize type of 'boundary_area'. It will be treated as String.
unknown OID 176071: failed to recognize type of 'lonlat'. It will be treated as String.

I also tried this on Postgres 14 with a fresh initialization, and it errored in the same fashion as before on db:migrate.

Not sure if this helps any further, but this is from PSQL (same results in test and development DBs)

talos_development=# select postgis_version();
            postgis_version            
---------------------------------------
 3.1 USE_GEOS=1 USE_PROJ=1 USE_STATS=1
(1 row)

talos_development=# show search_path;
   search_path   
-----------------
 "$user", public
(1 row)
keithdoggett commented 2 years ago

Hi @jathayde I was unable to reproduce the issue after installing that Gemfile as well. It appears that none of the spatial types are being registered in the ActiveRecord type map (the change in the annotations shows that the sql type is not being parsed properly). See: https://github.com/rgeo/activerecord-postgis-adapter/blob/a22aafadbe8921ea1ca85c27c71ba26be38073ad/lib/active_record/connection_adapters/postgis_adapter.rb#L66-L92.

It seems like you're just using the wrong adapter or somehow the adapter is getting switched. I was able to replicate your issues by changing the adapter from postgis to postgresql in the database.yml file. Can you ensure that your database.yml is configured properly and there's no other configurations that might be changing the adapter somehow?

jathayde commented 2 years ago

Ah that helped break the mental lock. DATABASE_URL is an environment variable for url in the database.yml file. That URL pointed to postgres://localhost:5432 instead of postgis://localhost:5432. The URL hack I had in place for Heroku production fixed it: url: <%= ENV.fetch("DATABASE_URL").gsub(/postgres/, 'postgis') %>

So while the adapter pointed to postgis, the URL did not.

Thanks for your help and patience!

keithdoggett commented 2 years ago

That's great to hear glad everything's working now!