Rails + PostGIS迁移数据库时出现错误

12

我正在跟随Daniel Azuma在Rails中使用地理空间分析的讲座,但是在第二个项目中每次运行rake db:migrate时都遇到了困难。

我的设置细节如下:我正在使用Postgres.app运行Postgresql,这给我提供了Postgres 9.1.3和PostGIS 2.0.0的版本。我在database.yml文件和运行迁移时遇到了一些问题。(我已经添加了相关的gems并在application.rb中引用了它们的信息)

我的database.yml文件看起来像这样:

 development:
   adapter: postgis
   postgis_extension: true
   host: localhost
   encoding: unicode
   database: my_app_development
   pool: 5
   username: my_app
   password:
如果我添加以下行 schema_search_path: "public,postgis",就会出现如下问题:
 rake aborted!
 PG::Error: ERROR:  schema "postgis" does not exist
 : SET search_path TO public,postgis
如果我删除那行代码,在尝试迁移我的数据库时会收到以下错误信息:
rake aborted!
PG::Error: ERROR:  relation "geometry_columns" does not exist
LINE 1: SELECT * FROM geometry_columns WHERE f_table_name='schema_mi...                       ^
: SELECT * FROM geometry_columns WHERE f_table_name='schema_migrations'

有人有想法怎么解决这些问题吗?


包括一个迁移,引用多边形作为数据类型。但是我认为不需要创建额外的迁移来处理几何列表,应该参考postgis适配器。 - tomciopp
你在这个问题上得到解决方案了吗?我也有同样的问题。 - Martin
6个回答

18

将PostGIS扩展从public模式中删除并重新创建到postgis模式中。

DROP EXTENSION PostGIS;

CREATE SCHEMA postgis;
CREATE EXTENSION PostGIS WITH SCHEMA postgis;
GRANT ALL ON postgis.geometry_columns TO PUBLIC;
GRANT ALL ON postgis.spatial_ref_sys TO PUBLIC

database.yml 文件也应该被修改为 schema_search_path: public, postgis - Jerome

10

以下是我如何解决这个问题。首先,我创建了一个新的迁移以将postgis添加到数据库中。(我已经通过Homebrew在Mac上安装了postgis和postgresql。)

rails g migration add_postgis_to_database

在迁移文件中,我删除了change方法并使用execute方法添加了POSTGIS。

execute("CREATE EXTENSION postgis;")

之后你可以检查数据库以确保postgis可用。

psql your_database_name
SELECT PostGIS_full_version();

1
只是为了明确,迁移文件应该长这样:class AddPostgisToDatabase < ActiveRecord::Migration execute("CREATE EXTENSION postgis;") end - dysbulic
@will rails g migration 会为你提供一个模板,让你可以将这段代码放在 change 块内或者编写自己的 up 方法。 - tadman
晚来一步... @tomciopp 我在我的 Mac 应用程序上使用了您的解决方案,并解决了问题。然而,在一个更新的应用程序中,这个 CREATE EXTENSION 迁移导致了相同的错误。我得出结论,这必须是安装过程中缺少的某些任务。 - Jerome

3
实际上,安装命令需要调用postgis版本。
sudo apt-get install -y postgis postgresql-9.3-postgis-2.1

最简单的方法就是声明。
sudo -u postgres psql -c "CREATE EXTENSION postgis" your-pg-database-name

避免迁移中的问题。

2
您使用的是哪个版本的PostgreSQL?EXTENSION功能在9.1中出现。扩展是一种方便的方式,可以将多个对象加载到一个包中。
如果您的版本低于9.1,则可能能够按照这些说明(所有-f命令)加载PostGIS。升级也可能是一个好主意,但这取决于您。

我目前正在运行9.1.4版本,我相信这是postgres的最新版本。 - tomciopp
是的,我发现即使在pg 9.4上,我仍然需要像这样“老方法”来做。不确定为什么EXTENSION命令不能解决我的问题。我在OpenStreetMap维基上找到了这些指令,它们实际上是相同的(运行这些SQL文件):http://wiki.openstreetmap.org/wiki/PostGIS/Installation#Ubuntu_14.10.2B_2 - Harry Wood

1
我遇到了同样的问题,尽管@Raido的解决方案修复了db:migrate的问题,但是在创建租户时(例如在db:seed期间),使用Apartment gem仍然存在问题。
我发现Rails会自动将enable_extension "postgis"添加到schema.rb中,而Apartment使用它来创建租户模式。我不确定为什么Apartment不使用现有的postgis扩展(也许是在创建租户时search_path出现了问题),但这会导致相同的错误。
解决方案(如果可以这么说)是从schema.rb中简单地删除enable_extension "postgis"行。这种方法的唯一问题是,任何触发schema.rb刷新的后续迁移都会重新添加该行。
另外,我使用了Apartment方法,将postgis扩展添加到shared_extensions模式中,而不是它自己的模式。我的lib/tasks/db_extensions.rake如下:
namespace :db do
  desc 'Also create shared_extensions Schema'
  task :extensions => :environment  do
    # Create Schema
    ActiveRecord::Base.connection.execute 'CREATE SCHEMA IF NOT EXISTS shared_extensions;'
    # Enable Hstore
    ActiveRecord::Base.connection.execute 'CREATE EXTENSION IF NOT EXISTS HSTORE SCHEMA shared_extensions;'
    # Enable uuid-ossp for uuid_generate_v1mc()
    ActiveRecord::Base.connection.execute 'CREATE EXTENSION IF NOT EXISTS "uuid-ossp" SCHEMA shared_extensions;'
    # Enable postgis extension for geographic data types
    ActiveRecord::Base.connection.execute 'DROP EXTENSION IF EXISTS postgis;'
    ActiveRecord::Base.connection.execute 'CREATE EXTENSION postgis WITH SCHEMA shared_extensions;'
    ActiveRecord::Base.connection.execute 'GRANT USAGE ON SCHEMA shared_extensions to PUBLIC;'
    puts 'Created extensions'
  end
end

Rake::Task["db:create"].enhance do
  Rake::Task["db:extensions"].invoke
end

Rake::Task["db:test:purge"].enhance do
  Rake::Task["db:extensions"].invoke
end

我的 database.yml 文件如下:

postgis_options: &postgis_options
  adapter: postgis
  postgis_extension: postgis # default is postgis
  postgis_schema: shared_extensions # default is public

default: &default
  schema_search_path: 'public,shared_extensions'
  encoding: utf8
  <<: *postgis_options

...

production:
  <<: *default
  url: <%= ENV['DATABASE_URL'].try(:sub, /^postgres/, 'postgis') %>

虽然不是最理想的,但它能够工作。也许这会为使用PostGIS和Apartment的某些人节省一两个小时。如果有比从schema.rb中删除enable_extension调用更好的解决方案,我很感兴趣 :)


0

请确保您已经安装了这个

sudo apt-get install postgresql-9.3-postgis

我之前也遇到了同样的问题,因为缺少了这个包。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接