sql >> データベース >  >> RDS >> PostgreSQL

Postgres Herokuの以前のバックアップから特定のデータを復元するにはどうすればよいですか? (例:誤って削除された行)

    概要/TL;DR

    3つのステップで、非常に簡単に実行できます。

    INSERT INTO production_db.table_name
    SELECT * FROM backup_db.table_name -- backup_db being remote
    

    最初にバックアップをローカルにインストールし、次にSQLスクリプトを取得し、3番目に ngrok>

    行こう?

    1。 Heroku でダンプファイルをダウンロードします どこかにダンプします:

    • いくつかのサーバーが利用可能な場合は、リモートデータベースでこれを行うことができます。しかし、私のように、Herokuやその他の場所に別の本番データベースをプロビジョニングしたくない場合は、ローカルで完全にプロビジョニングできます。
    • PGAdmin を使用するのが好きです (Linux、Mac、Windowsで利用可能)が、コマンドラインとpsqlを使用 (これを読むことによって(rel ="nofollow noreferrer noopener" href ="https://stackoverflow.com/questions/2732474/restore-a-postgres-backup-file-using-the-command-line">投稿 例による)
    • PGAdminでは、Create a databaseします。 。次に、それを右クリックして、restoreを使用します 関数。ダンプファイルを選択し、[Restore]をクリックします これで準備は完了です:バックアップデータはローカルで利用できます! よくできました!

    2。リモートデータベースからアクセスします

    私は次のことをしたかった:

    SELECT * FROM backup_db.table_name
    -- So I could then do
    INSERT INTO production_db.table_name
    SELECT * FROM backup_db.table_name
    

    そして、私はすべて設定されます。とても簡単ですよね?かなり明白?これはすでに何百回も行われているに違いありません。いいえ!

    db_linkというユーティリティがあります Postgres 9.1以降では、次の構文が適用されるため、かなり制約があります。

    SELECT fname, lname FROM db_link('host=localhost dbname=backup-28-08', 'SELECT fname, lname FROM users') AS remote (varchar255 fname varchar255 lname)
    

    すべての列名は、そのタイプを含めて2回繰り返す必要があります。かなり重いので、単純なSELECT * FROM backup_db.table_nameにはほど遠いです。

    したがって、ここでの考え方は、information_schemaを使用することです。 テーブルの内容。各テーブルをその列名やタイプなどで説明します。この質問はSOで見つかりました:ローカルの既存のタイプからdblink列定義リストを指定します 大いに助けてくれました (ventrm に感​​謝します 。

    しかし、その解決策は2段階のプロセスでした。最初に関数を生成し、次にクエリを実行しました。

    SELECT dblink_star_func('dbname=ben', 'public', 'test');
    SELECT * FROM star_test() WHERE data = 'success';
    

    そして、私はまだ1ライナーを目指していました。少し苦労した後(SQLの第一人者ではない)、要点は次のとおりです:https://gist.github。 com / augnustin / d30973ea8b5bf0067841

    私は今できる:

    SELECT * FROM remote_db(NULL::users) -- (Still not 100% about why I need the NULL::)
    -- And also
    INSERT INTO users
    SELECT * FROM remote_db(NULL::users)
    

    素晴らしいですよね?

    3。ローカルホストにリモートでアクセスする

    リモートデータベースがすでにインターネットから利用できる場合(=IPアドレス、ドメイン名があります。たとえば、Herokuの場合は次のようになります:ec2-54-217-229-169.eu-west-1.compute.amazonaws.com:5672/df68cfpbufjd9pこの手順はスキップできます 。ただし、ローカルデータベースを使用する場合は、外部から利用できるようにする必要があります(Herokuデータベースがアクセスできるようにするため)。

    このために、私は素晴らしいngrok を使用します

    インストールしたら、次のコマンドを入力するだけです。

    ngrok -proto=tcp 5432 #5432 being the default port for Postgresql. (Adapt if necessary)
                                                                                                                                                                                                        
    Tunnel Status                 online                                                                                                                                                                
    Version                       1.7/1.6                                                                                                                                                               
    Forwarding                    tcp://ngrok.com:51727 -> 127.0.0.1:5432                                                                                                                               
    Web Interface                 127.0.0.1:4040                                                                                                                                                        
    # Conn                        0                                                                                                                                                                     
    Avg Conn Time                 0.00ms    
    

    そして、あなたはdb_linkを差し込むだけでよいでしょう (要点)host=ngrock.com port=51727 そして、あなたは行ってもいい

    4。さらに進む

    これには多くの可能な改善があります。これが私がすでに見たものです:

    • スクリプトをdb_linkのデフォルト機能と見なす 機能
    • データベース構造がバックアップと本番環境で異なる場合、よりエラーが発生しにくくなります
    • データベースの結果とバックアップの結果を比較するツールを作成する(差分行のみを返すため)
    • 単純な結合を処理する
    • さらに、今のような生のSQLの代わりにバックエンドオブジェクトの操作を可能にするアプリケーションレベルのアダプター(RailsのActiveRecordなど)を用意することもできます

    私が明確だったことを願っています!それ以外の場合は詳細をお問い合わせください




    1. Moqを使用してMySQLデータベースに挿入クエリをモックする

    2. Pythonでの時間指定メールリマインダー

    3. 欠落しているインデックスを盲目的に作成しないでください。

    4. Slick and bonecp:org.postgresql.util.PSQLException:FATAL:申し訳ありませんが、クライアントが多すぎてすでにエラーが発生しています