针对现有应用将Sqlite3切换到PostgreSQL

时间:2012-09-17 19:22:34

标签: ruby-on-rails postgresql heroku sqlite

我正在尝试将开发(和测试/生产)数据库切换到PostgreSQL,以便将rails应用程序部署到Heroku。

按照他们的指示和一个railscast,环顾StackOverflow和Google以正确的方式重写我的database.yml文件并做其他所有事情,但我遇到了很多问题,所以我希望有人可以提供帮助我弄清楚我还需要做什么。我只会解释一下我在下面尝试过的内容。

一个主要问题是如何处理我的database.yml文件。许多网站不同意,或者根本没有任何用于池或用户名或编码的条目(或者就此而言,整个生产环境)。这是我在一些环顾四周并结合后最终得到的结果。这应该有用吗?:

development:
  adapter: postgresql
  encoding: unicode
  database: <appname>_development
  pool: 5
  username: <username>
  password: <password>

test:
  adapter: postgresql
  database: <appname>_test
  username: <username>
  password: <password>
  host: localhost

什么是游泳池?我需要编码吗?为什么这么多例子在yml文件中没有生产部分?

根据Railscast的建议,我自行安装了PostgreSQL,然后初始化了db,然后执行了这一行。

pg_ctl -D /usr/local/var/postgres -l /usr/local/var/postgres/server.log start

在另一个StackOverflow回答之后,我确保我的Postgres位于/ usr / local / bin / postgres目录中,并且我将此行添加到我的.bash_profile文件中。

export PATH="/Applications/Postgres.app/Contents/MacOS/bin:$PATH"

另外在Railscast的建议中,我安装了点击宝石,并执行了以下几行:

taps server sqlite://db.development.sqlite3 <username> <password>

然后打开一个新标签并执行:

taps pull postgresql://<username>@localhost/<appname>_development http://localhost//5000

但是当我输入时,我收到以下错误:

Failed to connect to database:
  Sequel::AdapterNotFound -> LoadError: cannot load such file -- sequel/adapters/postgresql

当然,我做错了。 (例如,我应该从sqlite3数据库中取出吗?我怎么知道它的url?)。但我不知道如何开始排除故障,所以我想我会寻求帮助。

谢谢!

5 个答案:

答案 0 :(得分:8)

Heroku,以及“database.yml”文件的“生产”部分

Heroku将忽略您的database.yml文件所说的生产内容。 Heroku将为Bamboo和Cedar堆栈自动为production注入自己的配置。换句话说 - 将production留空 - 在部署到Bamboo或Cedar堆栈时不需要它。

另一方面,如果您正在部署到Amazon Web Services,但使用Heroku's hosted Postgres solution作为后端数据库(它本身在AWS上运行),那么production内指定database.yml部分。

“水龙头”宝石

这似乎是一个gem,它允许您将数据从现有数据库(SQLite,为您)迁移到新数据库(PostgreSQL,我希望您将从此处开始用于本地开发)。我没有读太多内容,但我猜测taps使用ActiveRecord(或其他ORM解决方案)从它支持的任何数据库中读取记录,然后使用ActiveRecord将数据写回到目标数据库。通过使用ActiveRecord作为一种数据库间转换器,您可以避免编写特定于数据库的查询来移动数据。

话虽如此,如果您的本地数据库只是开发数据,并假设它可以重新创建(它应该是 - 它只是开发数据),那么您可以放弃使用{{ 1}}完全。只需将您的开发数据从SQLite迁移到Postgres - 只需停止使用SQLite并开始使用Postgres,其中包含已运行所有迁移的空数据库或其上的taps

可以通过Populator创建易于重新创建的优秀开发数据(为了您将来的需求 - 我现在不用太担心)。

“无法连接到数据库:”错误

您安装了the pg gem吗?这是Rails与PostgreSQL服务器通信所需的宝石。我对这个错误的解释表明你只是错过了db:schema:load宝石,因此,“Sequel :: AdapterNotFound”

游泳池

池是您希望从应用程序向数据库提供的并发连接数。使用SQLite,您可以指定此项以允许一定数量的并发读取。 SQLite (contrary to what is implied by its documentation) does not support concurrent writes

只要您的应用由多个Web实例提供服务,该池就可用于生产。池指定数据库的最大并发连接数,通常您的Web服务器将使用一个连接,每个活动请求,每个线程或其附近。我在这里捏造技术细节,但重点是需要支持的并发性越多(同时请求越多),可能需要的连接越多。

如前所述,Heroku无论如何都会忽略它,所以指定它是没有意义的,在本地开发中你可能一次只能发出一个请求,所以将它设置为pg可能看起来像与将其设置为1相同。

那么,当目前正在使用池中的所有连接时会发生什么?任何后续请求都会排队,直到连接可用,或者直到连接超时,以先到者为准。

有关连接池here的更多信息。

答案 1 :(得分:3)

Taps使用Sequel,Sequel使用postgres://...代替postgresql://...连接字符串。尝试:taps pull postgres://<username>@localhost/<appname>_development http://localhost//5000

答案 2 :(得分:1)

我最近这样做了,我的database.yml只使用:

development:
  adapter: postgresql
  username: my_user
  database: my_project_development

如果您在Heroku上的Postgres数据库中有数据,则可以heroku db:pull填充Postgres开发数据库。否则,您可能可能 db:push您的Sqlite数据(从您的机器,使用旧的database.yml配置)到Heroku,更新您的database.yml然后执行db:pull

答案 3 :(得分:1)

这通常是我用于postgres的内容:

production:
  adapter: postgresql
  encoding: utf8
  database: app_name
  pool: 5
  host: localhost
  username: username
  password: password

另外,请记住,yaml可能很糟糕,所以请务必避免使用标签,并在格式化中仅使用空格。

答案 4 :(得分:0)

您的RoR应用程序从SQLite迁移到Postgres需要10分钟

这是假设您在sqlite中有一个开发数据库,​​并且想要将结构和数据移至postgres。

您首先需要使用具有您的用户名here are the postgres install docs

的用户在本地安装和配置Postgres。

所需的软件:postgresql,pgloader


步骤

  1. 安装pgloader / postgres,并确保postgresql在您的系统上运行
  2. 备份sqlite-将development.sql复制到development_old.sql
  3. gem 'pg'添加到Gemfile的主要部分
  4. 捆绑安装
  5. 更新config / database.yml(请参见下面的示例)
  6. rake db:setup
  7. cd [应用程序根目录]
  8. 使用来自sqlite的数据加载postgres数据库

pgloader ./db/development.sqlite3 postgresql:///[name of postgres dev db]

  1. 从您的gemfile中删除gem 'sqlite3'
  2. 捆绑安装
  3. 启动服务器-rails server
  4. test by visiting app at localhost:3000

如果您遇到问题或极端情况,这里有一些资源可以帮助您。

资源:

database_sample.yml

default: &default
  adapter: postgresql
  encoding: unicode
  host: localhost
  port: 5432
  # For details on connection pooling, see Rails configuration guide
  # http://guides.rubyonrails.org/configuring.html#database-pooling
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  timeout: 5000

development:
  <<: *default
  database: [name of app]_dev

test:
  <<: *default
  database: [name of app]_test

staging:
  <<: *default
  database: [name of app]

production:
  <<: *default
  database: [name of app]