sql >> Database >  >> RDS >> Sqlserver

Hoe panda's DataFrame upsert naar Microsoft SQL Server-tabel?

Er zijn twee opties:

  1. Gebruik een MERGE statement in plaats van INSERT ... ON CONFLICT .
  2. Gebruik een UPDATE statement met een JOIN , gevolgd door een voorwaardelijke INSERT .

De T-SQL-documentatie voor MERGE zegt:

Prestatietip:het voorwaardelijke gedrag dat wordt beschreven voor de MERGE-instructie werkt het beste wanneer de twee tabellen een complexe combinatie van overeenkomende kenmerken hebben. Bijvoorbeeld een rij invoegen als deze niet bestaat, of een rij bijwerken als deze overeenkomt. Wanneer u eenvoudig een tabel bijwerkt op basis van de rijen van een andere tabel, verbetert u de prestaties en schaalbaarheid met de basisinstructies INSERT, UPDATE en DELETE.

In veel gevallen is het sneller en minder ingewikkeld om gewoon de aparte UPDATE . te gebruiken en INSERT verklaringen.

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. Coalesce gebruiken in MySQL

  2. Hoe PCI-compliance voor MySQL en MariaDB te bereiken met ClusterControl - The Replay

  3. Hoe de laatste rij te lezen met SQL Server

  4. SQL Server verbinden met Oracle