#342 Migrating to PostgreSQL
Apr 17, 2012 | 8 minutes | Active Record, Tools
Postgres is a feature-packed relational database that every Rails developer should consider using. Here you will learn how to install it, add it to a new application, and transition from an existing SQLite app using the "taps" gem.
- Download:
- source code
- mp4
- m4v
- webm
- ogv
Great episode!
A small side note: On Debian/Ubuntu/Mint Linux, you'll need
libpq-dev
(Postgres headers) to install thepg
gem, notlibpg...
. That annoys me every time I setup a new server... ;-)This is easy to understand:
foo
package provides binary executable of foo.foo-dev
package contains header(.h) and library(.so) files for compiling related sources.Since
pg
gem is a native gem that needs to be compiled against pg library, you needlibpq-dev
.He means that its annoying to use "libpq" instead of "libpg" (the average joe won't know that thats the name of the library) - not the "-dev" part.
I recently switched from MySQL to PostgreSQL and couldn't be happier. The performance i get out of pg is great!
I found that migrating my data from MySQL to pg was a challenge though and i wanted to point anyone who's currently going through that @ this post: http://ruby.zigzo.com/2011/12/03/migrating-data-from-mysql-to-postgresql/
Basically it's a record of how I was able to migrate data from mysql -> pg using a gem by Max Lapshin.
BTW i should also add... i <3 the taps gem!!
Nice one Ryan! I've been thinking about switching ot PG.
If you do a follow-up, could you cover how to do a PG version of a mysqldump please? And then how to put such a dump back into a (new) DB?
(Or some other way to backup/restore a db, thanks!)
Edit: just found:
http://linux.die.net/man/1/pg_dump
http://linux.die.net/man/1/pg_restorev
you shouldn't need pg_restore
psql has a -f switch that takes a file as an argument
Thanks Omar.
Just a quick note to say I asked the author of postgresguide.com if he could post some tips on backing up and restoring, and he promptly published the following page!
http://postgresguide.com/tips/backup-restore.html
I think with that info and Ryan's screencast... I am ready to give PG a go :D
AWESOME!
First time i'd heard of taps makes it a ton easier to make the jump!
Sorry but I think this episode is far below average level: nearly everything is obvious and can be googled easily.
Bouh!
Helpful for me. It's nice to have a visual walkthrough so I can see it step by step, especially since I'm new.
@Sergey Averyanov Do you know what they say about guys who claim to have big guns?
It really helped me..
This is AWESOME! My only problem is I installed via homebrew on Lion and when I do which psql I get:
/usr/bin/psql
How can I point it to the homebrew version?
You might have to brew link it.
@blackpond: Edit /etc/paths and make sure /usr/local/bin is above /usr/bin in the file. Open a new shell, and you're good to go!
P.S. If you have already installed the postgres gem, uninstall it and then re-install it.
Thanks!
Thanks, same problem here, and same solution.
This fix my Problem!
thanks i ran into this problem too!! was driving me crazy...
Where do I edit/find etc/paths?
THANK YOU!
Thanks!!
Another thank you!
@blackpond: Homebrew by design requires that in your user profile file (i.e. .bashrc or .profile or .bash_profile), that your set /usr/local/bin ahead of /usr/bin to avoid clashes with system software tools that may exist in other paths on your machine. it is important that you override the system paths to use homebrew installations as default.
Ah! Thanks for explaining that, that's pretty clear to me now.
Long been a PostgreSQL fan so great to see this being covered.
@anyone: taps is great, but don't rely on the record count, it stops working when you have more than 400 records
Love the screencast, thanks for mentioning my hstore article :)
Taps looks interesting, but complicated. The yaml_db gem looks like a simple way to backup and restore data. Does anyone have any experience using yaml_db to migrate from sqlite to PG?
Heroku's
db:pull
functionality was formerly based on yaml_db and has since moved to taps. I have had less problems with taps, though, i've used yaml_db to change schema in mass on existing data.Is it possible only to push certain tables when using TAPS. I´m using a MYSQL DB in development, and need to transfer my users table and images table to production, which uses Postgresql.... Any suggestions?
Great to see this article, PostgreSQL is by far the best choice in many ways, if you want to create an application with accounts that might not have relation (like basecamp) you can create multitenant databases with the schema feature from PostgeSQL. I Have used it with bonsaierp.com
I followed the instructions for upgrading PostgreSQL on a new install of OS X Lion by typing "brew install postgresql."
But I think I am having a problem:
"psql --version" returns psql (PostgreSQL) 9.0.5
"which psql" returns /usr/bin/psql
"postgres --version" returns postgres (PostgreSQL) 9.1.3
/usr/local/bin/postgres
In the screencast, when Ryan types "psql --version", it's listed as postgres (PostgreSQL) 9.1.3. And "which psql" also returns "/usr/local/bin/psql" for Ryan.
I'm just confused and I'm not sure what to do, if anything.
@heyitsmeross: See my earlier comments @blackpond. It's just a path problem.
You can change this in your .bashrc / .bash_profile / .zshrc or do as I've done and change it where it originates, in /etc/paths.
Homebrew's main repository doesn't usually include packages that have already been installed, so the path won't have been an issue for you until now.
If you start psql using this command
'pg_ctl -D /usr/local/var/postgres -l logfile start'
You will be able to run the RVM version just installed. Not sure if this is correct but just worked for me
I got the same, but after reinstall the pg gem, everything works fine.
I like the taps gem :) Thank you Ryan.
if you dont want to use the psql cli, you can try pgAdmin.
http://www.pgadmin.org/
So far the best GUI for pg i've used is Navicat Premium ... and by "best" i mean... Not as bad as the worst lol
Wish Sequel Pro supported pg! :)
Anyone on a Mac coming along who doesn't like PgAdmin (and Navicat seems to be dying), might want to try http://www.valentina-db.com/
Nice native UI, and the free version is certainly capable enough for individuals and small teams; orgs big enough to effectively use the Pro features should find the price reasonable.
Really glad to see postgres covered here!
A couple of tips:
rbates
in your case, you can simply ommit bothusername
andpassword
from database.yml. The underlying library will default to that user name. That way other developers working on the same project can use the same database.yml.postgres:///store_development
.Finally, check out valkyrie, the likely successor of taps.
Thanks!
Thank you for the tips. Very useful information. I had not heard of Valkyrie before but looks more convenient than Taps.
Thanks for the valkyrie tip - I've started using it - super fast and simple.
Taps stopped working with Rails 3.2.5 for some reason, so I thought I'd finally give Valkyrie a try.
Whoa! Nice. Easier than I expected, although it's significantly slower pushing local data to my remote postgre db server on Linode.
I'd like to second that. I spent an hour fiddling with Taps. I was done with my intended task five minutes after hearing this post about valkyrie. Just lovely. Thanks!
Thanks for the tip.
I tried to ommit username and password, and I'm still getting the "no password supplied" error when I try to scaffold a model.
Any idea what to try next?
Valkyrie looks interesting. I'm using rbenv, installing the gem, how do you get it to work from the command line as in the example?
A simple note:
pg
gem uses prepare statement in production env by default, which is different from MySQL.This can be an issue if you are using unicorn. You may got
PGError: ERROR: prepared statement "a3" already exists
after several requests.To solve this, make sure each unicorn process uses its own database connection by adding this to unicorn config file:
Hope this helps :)
Thank you so mach and it works for me.
And I want to point out a PGCon2009 video: PostgreSQL as a secret weapon for high-performance Ruby on Rails applications.
It suggests replace complex ActiveRecord logic with SQL to gain performance boost. The examples such as
act_as_tree
are impressing. The major disadvantage is that you can no more change db adapter easily.Thanks for the episode. I followed along and everything worked as expected (I did have to take aharte's advice to move /usr/local/bin above /usr/bin in /etc/paths to get 9.1.3 recognized).
However when I run "rails db" and try any commands against postgres I get a segmentation fault: 11. I installed postgres with the > brew install postgresql used in the railscast. I'm on Lion and > psql --version returns "psql (PostgreSQL) 9.1.3"
Any thoughts on the segmentation fault?
Thanks.
You might need to reinstall the pg gem, possibly with pg config path specified http://deveiate.org/code/pg/
Thanks for the tip house9!
Unfortunately I've never gotten it to work. I uninstalled the pg gem (I had both 0.13.2 and 0.14.0 installed) and re-installed 0.13.2 with:
sudo gem install pg --version 0.13.2 -- --with-pg-config=/usr/local/Cellar/postgresql/9.1.3/bin/pg_config
to no avail. Still getting "segmentation fault: 11" when I get to the psql prompt with "rails db" or with something like "psql -U [username] [db_name]".
My app requires pg 0.13.2.
It turns out I have xcode 4.3.2 installed but not the command line tools (xcode-> preferences -> downloads). When I ran brew --config it showed my Clang as: 2.1 build 163. After downloading/installing the xcode command line tools brew --config shows Clang: 3.1 build 318.
Then I reinstalled postgresql (brew uninstall postgresql / brew install postgresql) and restarted my server and BAM my postgres command line tools worked...no more segmentation fault.
Answer found on the homebrew github page: https://github.com/mxcl/homebrew/issues/10979
@torrents I got same error, Any luck so far?
No, unfortunately
how about MongoDB? what's the Pro/Cons?
would love an episode on mongoDB
There was an earlier episode on MongoDB here.
The PostgreSQL notices in the console really annoy me. You can turn them off by adding
min_messages: warning
in your database.yml file. See exampleI'm running into a problem after I try to run the initdb /user/local/var/postgres command. It says:
creating directory /user/local/var/postgres ... initdb: could not create directory "/user": Permission denied
I've tried Googling it, but no luck. Any ideas?
This may be a classic "is the computer plugged in?" solution, but did you try running the command with sudo?
sudo initdb /user/local/var/postgres
This is probably a case where your /usr/local/var/postgres path (or a parent) doesn't have read/write permissions. That's fine, you don't want read/write access on those directories.
I had the same problems as Nelson, ran sudo on initdb and this was my repsonse:
initdb: cannot be run as root
Please log in (using, e.g., "su") as the (unprivileged) user that will
own the server process.
Not sure where to go from here. Did a TON of googeling with no resolution.
This is a reply to a really old comment, but for anyone else that happens to run into this:
It's likely that you mistyped there. /usr/ instead of /user/ You're getting the permission error because you're trying to create a new directory from root (/) called user, instead of the existing path of /usr/local/var/
HTH
Hey Ryan. Thank you for this great tutorial!
I stumbled into one problem where
rake db:migrate:all
fails, because of a missing port configuration for the test environment. I documented the problem and the solution on Stackoverflow.One more question: Would you recommend to prepend
bundle exec
to the commands you used?Love the PG Text Search links. Very useful~!
Is it possible only to push certain tables when using TAPS. I´m using a MYSQL DB in development, and need to transfer my users table and images table to production, which uses Postgresql.... Any suggestions?
Oh, my production database is on Heroku by the way
Can anyone help with this error I am getting on rake db:create:all?
http://stackoverflow.com/questions/10423304/rake-dbcreateall-error-cant-convert-nil-to-string
Getting error of Rails: rake db:create:all (could not connect to server)
could not connect to server: No such file or directory Is the server running locally and accepting connections on Unix domain socket "/tmp/.s.PGSQL.5432"?
http://stackoverflow.com/questions/10482853/rails-rake-dbcreateall-could-not-connect-to-server
pg_ctl start
before running your rake task.I had the same problem, in my case I had to reinstall the pg gem and everything worked fine. This post was useful:
http://tammersaleh.com/posts/installing-postgresql-for-rails-3-1-on-lion
I have a problem when running my tests.
Everytime I try to
rake db:test:prepare
I getPG::Error: ERROR: type "hstore" does not exist
I'm not able to run my tests now :(
Where you able to find a solution to this? I'm facing the same problem.
Sure, everyone, who has
problem, can easily fix this.
Run:
(The first one's the critical one, but second seems appropriate too.)
This changes the limits in the currently-running kernel. To make these values stick across reboots, add them to /etc/sysctl.conf, like this:
Found this here
I was getting the error:
>$ rake db:migrate
'rake aborted!
FATAL: role "blog" does not exist'
so I had to create a superuser 'blog':
>$createuser -s blog
thanks
I had issues installing Postgres with the instructions in this Railscast. However I was able to get postgres running on my project with http://postgresapp.com/ and http://inductionapp.com/ (Hat tip to this stackoverflow thread).
/Applications
.PATH
In my case I added the following to ~/.bash_profile
export PATH="/Applications/Postgres.app/Contents/MacOS/bin:$PATH"
Check that Postgres.app is being loaded
/config/database.yml
bundle exec rake db:create:all
heroku db:pull
NOTE Select the last postgres option in Adapter dropdown
I've done all the above, but for some reason when I launch Induction, there is no "postgres" adapter available for me to choose. I am only given the options of redis, mongodb, and sqlite. Would anyone have ideas as to why thats the case?
I have uninstalled the previous Postgres that came on my machine (Mac OS X 10.8.2) and am only using Postgres server provided by Postgres.app. After doing the PATH fix you outlined above, I can access Postgres via the Terminal, but for some reason can't seem to get Induction to use it. Any help would be greatly appreciated.
Thanks in advance.
Interesting talk at NDC 2012 on not so well known tid bits of Postgres
You are a GOD.
Great episode. Transition went smoothly
i love you.
thanks guys, you are doing greate job!
I had problems with the encoding of my mysql database, so here is the trick:
From: https://github.com/ricardochimal/taps/issues/110#issuecomment-6364498
i was getting this error
could not connect to server: No such file or directory
Is the server running locally and accepting
connections on Unix domain socket "/var/pgsql_socket/.s.PGSQL.5432"?
and i solve it using host: localhost in the database.yml
Thanks! Was having trouble setting this up, great episode and much appreciated : )
For people having issues with transferring their data using taps, here is my fix:
https://github.com/ricardochimal/taps/issues/128#issuecomment-21049046
great episode, but i wish it had more info on how to set up and create a PostgreSQL database for new Postgres users. It would of definitely helped when migrating
To note if you're using JRuby and converting your database to postgresql for Heroku; the pg gem won't install. Instead use the activerecord-jdbcpostgresql-adapter gem in your gemfile per this Heroku dev center link
for those who are experiencing the error, "ERROR: Rack::Utils::OkJson::Error: cannot encode Symbol", i suggest using the taps-taps gem instead of just "taps." that's the only changed i had to make to get taps to work (it appears taps is incompatible with rack 1.5, but i can't say for sure). thanks to the following resource for solving the problem.
https://shellycloud.com/blog/2013/10/easy-database-migration-using-taps
thx!
I was having trouble to setup postgresql on my environment, the thing is that I'm working with https://c9.io, and just for the record, Cloud9 has his own setting up instructions https://docs.c9.io/docs/setting-up-postgresql.
after issuing taps server sqlite://db/development.sqlite3 mahesh secret command i got below error? how to rectify it?
Error:-`module:Templates': uninitialized constant Tilt::CompileSite (NameError)Did you mean? Complex