Completely copying a postgres table with SQL

前端 未结 7 1241
春和景丽
春和景丽 2021-01-30 06:13

DISCLAIMER: This question is similar to the stack overflow question here, but none of those answers work for my problem, as I will explain later.

I\'m t

相关标签:
7条回答
  • 2021-01-30 06:43

    The closest "miracle command" is something like

    pg_dump -t tablename | sed -r 's/\btablename\b/tablename_copy/' | psql -f -
    

    In particular, this takes care of creating the indexes after loading the table data.

    But that doesn't reset the sequences; you will have to script that yourself.

    0 讨论(0)
  • 2021-01-30 06:45

    To copy a table completely, including both table structure and data, you use the following statement:

    CREATE TABLE new_table AS 
    TABLE existing_table;
    

    To copy a table structure without data, you add the WITH NO DATA clause to the CREATE TABLE statement as follows:

    CREATE TABLE new_table AS 
    TABLE existing_table 
    WITH NO DATA;
    

    To copy a table with partial data from an existing table, you use the following statement:

    CREATE TABLE new_table AS 
    SELECT
    *
    FROM
        existing_table
    WHERE
        condition;
    
    0 讨论(0)
  • 2021-01-30 06:48

    Apparently you want to "rebuild" a table. If you only want to rebuild a table, not copy it, then you should use CLUSTER instead.

    SELECT count(*) FROM table; -- make a seq scan to make sure the table is at least
                                -- decently cached
    CLUSTER someindex ON table;
    

    You get to choose the index, try to pick one that suits your queries. You can always use the primary key if no other index is suitable.

    If your table is too large to be cached, CLUSTER can be slow though.

    0 讨论(0)
  • create table newTableName (like oldTableName including indexes); insert into newTableName select * from oldTableName

    This worked for me 9.3

    0 讨论(0)
  • 2021-01-30 07:03

    WARNING:

    All the answers which use pg_dump and any sort of regular expression to replace the name of the source table are really dangerous. What if your data contains the substring that you are trying to replace? You will end up changing your data!

    I propose a two-pass solution:

    1. eliminate data lines from the dump using some data-specific regexp
    2. perform search-and-replace on the remaining lines

    Here's an example written in Ruby:

    ruby -pe 'gsub(/(members?)/, "\\1_copy_20130320") unless $_ =~ /^\d+\t.*(?:t|f)$/' < members-production-20130320.sql > copy_members_table-20130320.sql
    

    In the above I am trying to copy "members" table into "members_copy_20130320". My data-specific regexp is /^\d+\t.*(?:t|f)$/

    The above type of solution works for me. Caveat emptor...

    edit:

    OK, here's another way in pseudo-shell syntax for the regexp-averse people:

    1. pg_dump -s -t mytable mydb > mytable_schema.sql
    2. search-and-replace table name in mytable_schema.sql > mytable_copy_schema.sql
    3. psql -f mytable_copy_schema.sql mydb

    4. pg_dump -a -t mytable mydb > mytable_data.sql

    5. replace "mytable" in the few SQL statement preceding the data section
    6. psql -f mytable_data.sql mydb
    0 讨论(0)
  • 2021-01-30 07:04

    The create table as feature in PostgreSQL may now be the answer the OP was looking for.

    https://www.postgresql.org/docs/9.5/static/sql-createtableas.html

    create table my_table_copy as
      select * from my_table
    

    This will create an identical table with the data.

    Adding with no data will copy the schema without the data.

    create table my_table_copy as
      select * from my_table
    with no data
    

    This will create the table with all the data, but without indexes and triggers etc.


    create table my_table_copy (like my_table including all)

    The create table like syntax will include all triggers, indexes, constraints, etc. But not include data.

    0 讨论(0)
提交回复
热议问题