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

pandasDataFrameをMicrosoftSQLServerテーブルにアップサートする方法は?

    2つのオプションがあります:

    1. MERGEを使用する INSERT ... ON CONFLICTの代わりにステートメント 。
    2. UPDATEを使用する JOINを含むステートメント 、その後に条件付きのINSERT

    MERGEのT-SQLドキュメントには次のように書かれています:

    パフォーマンスのヒント:MERGEステートメントで説明されている条件付きの動作は、2つのテーブルに一致する特性が複雑に混在している場合に最適に機能します。たとえば、行が存在しない場合は行を挿入し、一致する場合は行を更新します。別のテーブルの行に基づいて1つのテーブルを更新するだけの場合は、基本的なINSERT、UPDATE、およびDELETEステートメントを使用してパフォーマンスとスケーラビリティを向上させます。

    多くの場合、個別のUPDATEを使用する方が高速で複雑ではありません。 およびINSERT ステートメント。

    engine = sa.create_engine(
        connection_uri, fast_executemany=True, isolation_level="SERIALIZABLE"
    )
    
    with engine.begin() as conn:
        # step 0.0 - create test environment
        conn.execute(sa.text("DROP TABLE IF EXISTS main_table"))
        conn.execute(
            sa.text(
                "CREATE TABLE main_table (id int primary key, txt varchar(50))"
            )
        )
        conn.execute(
            sa.text(
                "INSERT INTO main_table (id, txt) VALUES (1, 'row 1 old text')"
            )
        )
        # step 0.1 - create DataFrame to UPSERT
        df = pd.DataFrame(
            [(2, "new row 2 text"), (1, "row 1 new text")], columns=["id", "txt"]
        )
    
        # step 1 - upload DataFrame to temporary table
        df.to_sql("#temp_table", conn, index=False, if_exists="replace")
    
        # step 2 - merge temp_table into main_table
        conn.execute(
            sa.text("""\
                UPDATE main SET main.txt = temp.txt
                FROM main_table main INNER JOIN #temp_table temp
                    ON main.id = temp.id
                """
            )
        )
        conn.execute(
            sa.text("""\
                INSERT INTO main_table (id, txt) 
                SELECT id, txt FROM #temp_table
                WHERE id NOT IN (SELECT id FROM main_table) 
                """
            )
        )
    
        # step 3 - confirm results
        result = conn.execute(sa.text("SELECT * FROM main_table ORDER BY id")).fetchall()
        print(result)  # [(1, 'row 1 new text'), (2, 'new row 2 text')]
    



    1. 2日前として取得されたJava1.7.0で実行されているSQL-Server(MSSQL-JDBC 3.0)の日付列

    2. クエリを使用してSQLデータベースの疑わしいモードを通常モードに変更する

    3. Oracleマネージドドライバーはasync/awaitを適切に使用できますか?

    4. 「SQLServerがコンポーネント「アドホック分散クエリ」のステートメント「OpenRowset/OpenDatasource」へのアクセスをブロックした」を修正