Sqlserver
 sql >> Datenbank >  >> RDS >> Sqlserver

Wie fügt man Pandas DataFrame in die Microsoft SQL Server-Tabelle ein?

Es gibt zwei Möglichkeiten:

  1. Verwenden Sie ein MERGE -Anweisung anstelle von INSERT ... ON CONFLICT .
  2. Verwenden Sie ein UPDATE Anweisung mit einem JOIN , gefolgt von einem bedingten INSERT .

Die T-SQL-Dokumentation für MERGE sagt:

Leistungstipp:Das für die MERGE-Anweisung beschriebene bedingte Verhalten funktioniert am besten, wenn die beiden Tabellen eine komplexe Mischung übereinstimmender Merkmale aufweisen. Beispielsweise das Einfügen einer Zeile, wenn sie nicht vorhanden ist, oder das Aktualisieren einer Zeile, wenn sie übereinstimmt. Wenn Sie einfach eine Tabelle basierend auf den Zeilen einer anderen Tabelle aktualisieren, verbessern Sie die Leistung und Skalierbarkeit mit einfachen INSERT-, UPDATE- und DELETE-Anweisungen.

In vielen Fällen ist es schneller und unkomplizierter, einfach das separate UPDATE zu verwenden und INSERT Aussagen.

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')]