How to restore a single table from a .sql postgres

2019-01-24 04:19发布

A table's rows were mistakenly deleted from the database. We have a db backup which results in a sql file that can restored like so:

psql -h localhost -d proddump -f /Users/U/Desktop/prod_db_backup/PostgreSQL/site_prod.sql

This ends up doing a full restore locally. But what we need is to restore a single table's rows to production. Any tips on how to make this work with PostgreSQL 9.1?

Thanks

5条回答
对你真心纯属浪费
2楼-- · 2019-01-24 04:47

Don't do SQL backups if you need single table restore, etc. Use pg_dump's -Fc option - the "custom" format. This can be restored using pg_restore. Selective restore is possible, as are all sorts of other handy features. pg_restore can convert a custom-format dump into an SQL dump later if you need it.

If you're stuck with an existing dump, your only options are:

  • Use a text editor to extract the target table data to a separate file and just restore that; or

  • Restore the dump to a throwaway database then use pg_dump to take a selective dump including just that table. Since it's throwaway, you can use a separate Pg instance on some unloaded fast-but-unsafe machine where you turn on all the "make it fast but eat my data if you like" options like fsync=off. You should NEVER set that in production.

查看更多
别忘想泡老子
3楼-- · 2019-01-24 04:47

I'm not aware of any tool for this, but this one-liner extracts precious_table from my_backup.sql file:

sed -n '/^COPY precious_table /,/^\\\.$/p' my_backup.sql
查看更多
啃猪蹄的小仙女
4楼-- · 2019-01-24 04:52

There is an easy way.

'pg_restore' has a '--table/-t' option.

pg_restore -a -t your_table /path/to/dump.sql

Use '-h' for remote host. See other options here

查看更多
啃猪蹄的小仙女
5楼-- · 2019-01-24 04:53

You can use grep + sed in roder to get table data:

First, you need to identify boundaries:

$ fgrep -Ehn '^(COPY |CREATE TABLE )' db.sql
49:CREATE TABLE test (
60:CREATE TABLE test2 (
71:CREATE TABLE test3 (
82:COPY test (i) FROM stdin;
100090:COPY test2 (i) FROM stdin;
200098:COPY test3 (i) FROM stdin;

In order to extract data for table test2:

sed -n '100090,200097p' < db.sql | sed -e 's/^COPY test2/COPY new_table_name/' > new_table_name.sql

Note, you need to subtract one from the second number (i.e exclude next copy stmt)

Now, you can load new_table_name.sql and restore data which you need. Now, you can load data into new table

查看更多
地球回转人心会变
6楼-- · 2019-01-24 05:04

I happen to have pg_dumpall dump around. And I would like to restore table named users from the database named edc, as you most likely will have equally named tables in different databases and even schemas.

For my case, the following sed oneliner works:

sed -ne '/^\\connect edc/,/^\\connect/{/\susers\(\s\|$\)/,/;\|\\\./p}' pg92.dump

What it does:

  1. /^\\connect edc/,/^\\connect/ limits the search to be the scope of my database;
  2. {…} will perform all inside commands for the range;
  3. /\susers\(\s\|$\)/ matches all lines with users on it's own, including at the end of the line;
  4. /;\|\\\./ matches lines with ; or containing \.
  5. p forces the matching lines to be outputted (note, that sed is invoked with -n).

Depending on the complexity of your data, you might need to tweak this.

All you have to do is to pipe sed output to the psql command with right switches.

查看更多
登录 后发表回答