Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Jak upsert pandy DataFrame do tabeli Microsoft SQL Server?

Istnieją dwie opcje:

  1. Użyj MERGE instrukcja zamiast INSERT ... ON CONFLICT .
  2. Użyj UPDATE oświadczenie z JOIN , po którym następuje warunkowe INSERT .

Dokumentacja T-SQL dla MERGE mówi:

Wskazówka dotycząca wydajności:warunkowe zachowanie opisane dla instrukcji MERGE działa najlepiej, gdy dwie tabele mają złożoną mieszankę dopasowanych cech. Na przykład wstawienie wiersza, jeśli nie istnieje, lub zaktualizowanie wiersza, jeśli pasuje. Po prostu aktualizując jedną tabelę na podstawie wierszy innej tabeli, popraw wydajność i skalowalność za pomocą podstawowych instrukcji INSERT, UPDATE i DELETE.

W wielu przypadkach szybsze i mniej skomplikowane jest użycie oddzielnej UPDATE i INSERT oświadczenia.

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. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jeśli nie określono opcji „Kolejność według”, jaką kolejność wybiera zapytanie dla zestawu rekordów?

  2. Zapytanie, aby uzyskać tylko liczby z ciągu

  3. Jak wykonać GROUP BY na aliasowanej kolumnie w MS-SQL Server?

  4. nierozwiązane odniesienie do obiektu [INFORMATION_SCHEMA].[TABLES]

  5. Używając GETDATE() w wielu miejscach, czy lepiej jest używać zmiennej?