Pandas: `.to_sql` рдореЗрдВ рд╡рд┐рдХрд▓реНрдк рдЬреЛрдбрд╝рдирд╛ (рдпрджрд┐ рдХреБрдВрдЬреА рдореМрдЬреВрдж рд╣реИ рддреЛ рдбрд╛рд▓реЗрдВ рдпрд╛ рдЕрдкрдбреЗрдЯ рдХрд░реЗрдВ)

рдХреЛ рдирд┐рд░реНрдорд┐рдд 1 рдирд╡ре░ 2016  ┬╖  42рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: pandas-dev/pandas

рдорд╛рди рд▓реЗрдВ рдХрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ person_age рдирд╛рдордХ рдПрдХ рдореМрдЬреВрджрд╛ SQL рддрд╛рд▓рд┐рдХрд╛ рд╣реИ, рдЬрд╣рд╛рдВ id рдкреНрд░рд╛рдердорд┐рдХ рдХреБрдВрдЬреА рд╣реИ:

    age
id  
1   18
2   42

рдФрд░ рдЖрдкрдХреЗ рдкрд╛рд╕ DataFrame рдореЗрдВ рдирдпрд╛ рдбреЗрдЯрд╛ рднреА рд╣реИ рдЬрд┐рд╕реЗ extra_data рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ

    age
id  
2   44
3   95

рддреЛ extra_data.to_sql() рдкрд░ рдПрдХ рд╡рд┐рдХрд▓реНрдк рд░рдЦрдирд╛ рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛ рдЬреЛ primary key рдЖрдзрд╛рд░ рдкрд░ рдкрдВрдХреНрддрд┐рдпреЛрдВ рдкрд░ INSERT рдпрд╛ UPDATE рд╡рд┐рдХрд▓реНрдк рдХреЗ рд╕рд╛рде SQL рдХреЛ DataFrame рдкрд╛рд╕ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ primary key ред

рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, id=2 рдкрдВрдХреНрддрд┐ age=44 рдЕрдкрдбреЗрдЯ рд╣реЛ рдЬрд╛рдПрдЧреА рдФрд░ id=3 рдкрдВрдХреНрддрд┐ рдЬреБрдбрд╝ рдЬрд╛рдПрдЧреА

рдЕрдкреЗрдХреНрд╖рд┐рдд рдЙрддреНрдкрд╛рджрди

    age
id  
1   18
2   44
3   95

(рд╢рд╛рдпрдж) рд╕рд╣рд╛рдпрдХ рдХреЛрдб рд╕рдВрджрд░реНрдн

рдореИрдВрдиреЗ рд╕рдорд╛рдзрд╛рди рдХреЗ рд╕рд╛рде рдЖрдиреЗ рдХреЗ рд▓рд┐рдП pandas sql.py рд╕реНрд░реЛрдд рдХреЛрдб рджреЗрдЦрд╛, рд▓реЗрдХрд┐рди рдореИрдВ рдЗрд╕рдХрд╛ рдкрд╛рд▓рди рдирд╣реАрдВ рдХрд░ рд╕рдХрд╛ред

рдЙрдкрд░реЛрдХреНрдд рдЙрджрд╛рд╣рд░рдг рдХреЛ рджреЛрд╣рд░рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдб

( sqlalchemy рдФрд░ sqlite рдХреЛ рдорд┐рд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХреНрд╖рдорд╛ рдпрд╛рдЪрдирд╛

import pandas as pd
from sqlalchemy import create_engine
import sqlite3
conn = sqlite3.connect('example.db')

c = conn.cursor()
c.execute('''DROP TABLE IF EXISTS person_age;''')
c.execute('''
          CREATE TABLE person_age
          (id INTEGER PRIMARY KEY ASC, age INTEGER NOT NULL)
          ''')
conn.commit()
conn.close()

##### Create original table

engine = create_engine("sqlite:///example.db")
sql_df = pd.DataFrame({'id' : [1, 2], 'age' : [18, 42]})

sql_df.to_sql('person_age', engine, if_exists='append', index=False)


#### Extra data to insert/update

extra_data = pd.DataFrame({'id' : [2, 3], 'age' : [44, 95]})
extra_data.set_index('id', inplace=True)

#### extra_data.to_sql()  with row update or insert option

expected_df = pd.DataFrame({'id': [1, 2, 3], 'age': [18, 44, 95]})
expected_df.set_index('id', inplace=True)

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

рдЬрдмрдХрд┐ INSERT OR UPDATE рд╕рднреА рдЗрдВрдЬрдиреЛрдВ рджреНрд╡рд╛рд░рд╛ рд╕рдорд░реНрдерд┐рдд рдирд╣реАрдВ рд╣реИ, рдбреЗрдЯрд╛рдлрд╝реНрд░реЗрдо рдЗрдВрдбреЗрдХреНрд╕ рдореЗрдВ рдкреНрд░рд╛рдердорд┐рдХ рдХреБрдВрдЬрд┐рдпреЛрдВ рдХреЗ рд╕реЗрдЯ рдХреЗ рд▓рд┐рдП рд▓рдХреНрд╖реНрдп рддрд╛рд▓рд┐рдХрд╛ рд╕реЗ рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреЛ рд╣рдЯрд╛рдХрд░ рдПрдХ INSERT OR REPLACE рдХреЛ рдЗрдВрдЬрди рдЕрдЬреНрдЮреЗрдп рдмрдирд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рдмрд╛рдж рдПрдХ рдЗрдВрд╕рд░реНрдЯ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ DataFrame рдореЗрдВ рд╕рднреА рдкрдВрдХреНрддрд┐рдпрд╛рдБред рдЖрдк рдЗрд╕реЗ рд▓реЗрди-рджреЗрди рдореЗрдВ рдХрд░рдирд╛ рдЪрд╛рд╣реЗрдВрдЧреЗред

рд╕рднреА 42 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

рдпрд╣ рдЕрдЪреНрдЫреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рд╣реЛрдЧреА, рд▓реЗрдХрд┐рди рдореБрдЦреНрдп рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рд╣рдо рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рдбреЗрдЯрд╛рдмреЗрд╕-рд╕реНрд╡рд╛рдж рд╕реНрд╡рддрдВрддреНрд░ рд╣реЛ рдФрд░ рдкрдВрдбреЛрдВ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП sqlalchemy рдХреЛрд░ (рдЗрд╕рд▓рд┐рдП sqlalchemy ORM рдирд╣реАрдВ) рдкрд░ рдЖрдзрд╛рд░рд┐рдд рд╣реЛред
рдЬрд┐рд╕рд╕реЗ рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдореБрд╢реНрдХрд┐рд▓ рд╣реЛ рдЬрд╛рдПрдЧрд╛..

рд╣рд╛рдБ, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдкрд╛рдВрдбрд╛ рдХреЗ рджрд╛рдпрд░реЗ рд╕реЗ рдмрд╛рд╣рд░ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЕрдкреНрд╕рд░реНрдЯ рд╕рднреА рдбреАрдмреА рдЗрдВрдЬрдиреЛрдВ рджреНрд╡рд╛рд░рд╛ рд╕рдорд░реНрдерд┐рдд рдирд╣реАрдВ рд╣реИрдВред

рдЬрдмрдХрд┐ INSERT OR UPDATE рд╕рднреА рдЗрдВрдЬрдиреЛрдВ рджреНрд╡рд╛рд░рд╛ рд╕рдорд░реНрдерд┐рдд рдирд╣реАрдВ рд╣реИ, рдбреЗрдЯрд╛рдлрд╝реНрд░реЗрдо рдЗрдВрдбреЗрдХреНрд╕ рдореЗрдВ рдкреНрд░рд╛рдердорд┐рдХ рдХреБрдВрдЬрд┐рдпреЛрдВ рдХреЗ рд╕реЗрдЯ рдХреЗ рд▓рд┐рдП рд▓рдХреНрд╖реНрдп рддрд╛рд▓рд┐рдХрд╛ рд╕реЗ рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреЛ рд╣рдЯрд╛рдХрд░ рдПрдХ INSERT OR REPLACE рдХреЛ рдЗрдВрдЬрди рдЕрдЬреНрдЮреЗрдп рдмрдирд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рдмрд╛рдж рдПрдХ рдЗрдВрд╕рд░реНрдЯ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ DataFrame рдореЗрдВ рд╕рднреА рдкрдВрдХреНрддрд┐рдпрд╛рдБред рдЖрдк рдЗрд╕реЗ рд▓реЗрди-рджреЗрди рдореЗрдВ рдХрд░рдирд╛ рдЪрд╛рд╣реЗрдВрдЧреЗред

@TomAugspurger рдХреНрдпрд╛ рд╣рдо рд╕рдорд░реНрдерд┐рдд рдбреАрдмреА рдЗрдВрдЬрди рдХреЗ рд▓рд┐рдП

рдореИрдВ рдпрд╣ рднреА рджреЗрдЦрдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ред рдореИрдВ рд╢реБрджреНрдз рдПрд╕рдХреНрдпреВрдПрд▓ рдФрд░ рдПрд╕рдХреНрдпреВрдПрд▓ рдХреАрдорд┐рдпрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдмреАрдЪ рдореЗрдВ рдлрдВрд╕ рдЧрдпрд╛ рд╣реВрдВ (рдЗрд╕реЗ рдЕрднреА рддрдХ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ рдорд┐рд▓рд╛ рд╣реИ, рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕рдХрд╛ рдХреБрдЫ рд╕рдВрдмрдВрдз рд╣реИ рдХрд┐ рдореИрдВ рдХреИрд╕реЗ рдбрд┐рдХреНрдЯреНрд╕ рдкрд╛рд╕ рдХрд░рддрд╛ рд╣реВрдВ)ред рдореИрдВ рдереЛрдХ рдбрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП psycopg2 COPY рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдЙрди рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдХреЗ рд▓рд┐рдП pd.to_sql рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЕрдЪреНрдЫрд╛ рд▓рдЧреЗрдЧрд╛ рдЬрд╣рд╛рдВ рд╕рдордп рдХреЗ рд╕рд╛рде рдореВрд▓реНрдп рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдореБрдЭреЗ рдереЛрдбрд╝рд╛ рдзреАрдорд╛ рдбрд╛рд▓рдиреЗ рдореЗрдВ рдХреЛрдИ рдлрд░реНрдХ рдирд╣реАрдВ рдкрдбрд╝рддрд╛ред

insert_values = df.to_dict(orient='records')
insert_statement = sqlalchemy.dialects.postgresql.insert(table).values(insert_values)
upsert_statement = insert_statement.on_conflict_do_update(
    constraint='fact_case_pkey',
    set_= df.to_dict(orient='dict')
)

рдФрд░ рд╢реБрджреНрдз рдПрд╕рдХреНрдпреВрдПрд▓:

def create_update_query(df, table=FACT_TABLE):
    """This function takes the Airflow execution date passes it to other functions"""
    columns = ', '.join([f'{col}' for col in DATABASE_COLUMNS])
    constraint = ', '.join([f'{col}' for col in PRIMARY_KEY])
    placeholder = ', '.join([f'%({col})s' for col in DATABASE_COLUMNS])
    values = placeholder
    updates = ', '.join([f'{col} = EXCLUDED.{col}' for col in DATABASE_COLUMNS])
    query = f"""INSERT INTO {table} ({columns}) 
    VALUES ({placeholder}) 
    ON CONFLICT ({constraint}) 
    DO UPDATE SET {updates};"""
    query.split()
    query = ' '.join(query.split())
    return query

def load_updates(df, connection=DATABASE):
    """Uses COPY from STDIN to load to Postgres
     :param df: The dataframe which is writing to StringIO, then loaded to the the database
     :param connection: Refers to a PostgresHook
    """
    conn = connection.get_conn()
    cursor = conn.cursor()
    df1 = df.where((pd.notnull(df)), None)
    insert_values = df1.to_dict(orient='records')
    for row in insert_values:
        cursor.execute(create_update_query(df), row)
        conn.commit()
    cursor.close()
    del cursor
    conn.close()

@ldacey рдЗрд╕ рд╢реИрд▓реА рдиреЗ рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдо рдХрд┐рдпрд╛ (insert_statement.excluded рдбреЗрдЯрд╛ рдХреА рдкрдВрдХреНрддрд┐ рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрдкрдирд╛рдо рд╣реИ рдЬреЛ рдмрд╛рдзрд╛ рдХрд╛ рдЙрд▓реНрд▓рдВрдШрди рдХрд░рддрд╛ рд╣реИ):

insert_values = merged_transactions_channels.to_dict(orient='records')
 insert_statement = sqlalchemy.dialects.postgresql.insert(orders_to_channels).values(insert_values)
    upsert_statement = insert_statement.on_conflict_do_update(
        constraint='orders_to_channels_pkey',
        set_={'channel_owner': insert_statement.excluded.channel_owner}
    )

@cdagnino рд╕рдордЧреНрд░ рдХреБрдВрдЬреА рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдпрд╣ рд╕реНрдирд┐рдкреЗрдЯ рдХрд╛рдо рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдЙрд╕ рдкрд░рд┐рджреГрд╢реНрдп рдХрд╛ рднреА рдзреНрдпрд╛рди рд░рдЦрдирд╛ рд╣реЛрдЧрд╛ред рдореИрдВ рдРрд╕рд╛ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ рдЦреЛрдЬрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реВрдВрдЧрд╛

рдЗрд╕ рдЕрджреНрдпрддрди рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рддрд░реАрдХрд╛ sqlachemy рдХреЗ рдмрд▓реНрдХ_рдЕрдкрдбреЗрдЯ_рдореИрдкрд┐рдВрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ

session.bulk_update_mappings(
  Table,
  pandas_df.to_dict(orient='records)
)

рдореИрдВ @neilfrndes рд╕реЗ рд╕рд╣рдордд

рд╢рд╛рдпрджред рдЕрдЧрд░ рдХреЛрдИ рдкреАрдЖрд░ рдмрдирд╛рддрд╛ рд╣реИред рдЖрдЧреЗ рд╡рд┐рдЪрд╛рд░ рдХрд░рдиреЗ рдкрд░, рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рдореИрдВ рдЗрд╕ рд╕рд┐рджреНрдзрд╛рдВрдд рдХрд╛ рд╡рд┐рд░реЛрдз рдХрд░ рд░рд╣рд╛ рд╣реВрдВ рдХрд┐ рдХреБрдЫ рдбреЗрдЯрд╛рдмреЗрд╕ рдЗрд╕рдХрд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдореИрдВ рдПрд╕рдХреНрдпреВрдПрд▓ рдХреЛрдб рд╕реЗ рдмрд╣реБрдд рдкрд░рд┐рдЪрд┐рдд рдирд╣реАрдВ рд╣реВрдВ, рдЗрд╕рд▓рд┐рдП рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рддрд░реАрдХрд╛ рдХреНрдпрд╛ рд╣реИред

рдПрдХ рд╕рдВрднрд╛рд╡рдирд╛ рдпрд╣ рд╣реИ рдХрд┐ рдЕрдЧрд░ рдпрд╣ рдкреАрдЖрд░ рдкреЗрд╢ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рддреЛ method рдХреЙрд▓ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдЕрдкреНрд╕рд░реНрдЯ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рдЙрджрд╛рд╣рд░рдг рдкреНрд░рджрд╛рди рдХрд░рдирд╛ рд╣реИ: https://github.com/pandas-dev/pandas/pull/21401

рдкреЛрд╕реНрдЯрдЧреНрд░реЗрдЬрд╝ рдХреЗ рд▓рд┐рдП рдЬреЛ рдХреБрдЫ рдРрд╕рд╛ рджрд┐рдЦрд╛рдИ рджреЗрдЧрд╛ (рдЕрд╡рд╛рдВрдЫрд┐рдд):

from sqlalchemy.dialects import postgresql

def pg_upsert(table, conn, keys, data_iter):
    for row in data:
        row_dict = dict(zip(keys, row))
        stmt = postgresql.insert(table).values(**row_dict)
        upsert_stmt = stmt.on_conflict_do_update(
            index_elements=table.index,
            set_=row_dict)
        conn.execute(upsert_stmt)

MySQL рдХреЗ рд▓рд┐рдП рдХреБрдЫ рдРрд╕рд╛ рд╣реА рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдкреЛрд╕реНрдЯрдЧреНрд░реЗрдЬ рдХреЗ рд▓рд┐рдП рдореИрдВ execute_values тАЛтАЛтАЛтАЛрдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реВрдВред рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдореЗрд░реА рдХреНрд╡реЗрд░реА рдзреНрд╡рдЬрд╛рдВрдХрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ jinja2 рдЯреЗрдореНрдкреНрд▓реЗрдЯ рд╣реИ рдХрд┐ рдореБрдЭреЗ рдЕрдкрдбреЗрдЯ рд╕реЗрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рдпрд╛ рдХреБрдЫ рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрд╣ рдХрд╛рдлреА рддреЗрдЬ рдФрд░ рд▓рдЪреАрд▓рд╛ рд░рд╣рд╛ рд╣реИред COPY рдпрд╛ copy_expert рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдЬрд┐рддрдирд╛ рддреЗрдЬрд╝ рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред

from psycopg2.extras import execute_values

df = df.where((pd.notnull(df)), None)
tuples = [tuple(x) for x in df.values]

`` with pg_conn: with pg_conn.cursor() as cur: execute_values(cur=cur, sql=insert_query, argslist=tuples, template=None, )

@ danich1 рдХреНрдпрд╛ рдЖрдк рдХреГрдкрдпрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╕реЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░реЗрдЧрд╛?

рдореИрдВрдиреЗ рдмрд▓реНрдХ_рдЕрдкрдбреЗрдЯ_рдореИрдкрд┐рдВрдЧ рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХреА рд▓реЗрдХрд┐рди рдореИрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЦреЛ рдЧрдпрд╛ рдФрд░ рдЗрд╕реЗ рдХрд╛рдо рдирд╣реАрдВ рдХрд░ рд╕рдХрд╛ред

@ cristianionescu92 рдПрдХ рдЙрджрд╛рд╣рд░рдг рдпрд╣ рд╣реЛрдЧрд╛:
рдореЗрд░реЗ рдкрд╛рд╕ рдирд┐рдореНрди рдлрд╝реАрд▓реНрдб рд╡рд╛рд▓реЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдирд╛рдордХ рдПрдХ рдЯреЗрдмрд▓ рд╣реИ: рдЖрдИрдбреА рдФрд░ рдирд╛рдоред

| рдЖрдИрдбреА | рдирд╛рдо |
| --- | --- |
| 0 | рдЬреЙрди |
| 1 | рдЬреЛ |
| 2 | рд╣реИрд░реА |

рдореЗрд░реЗ рдкрд╛рд╕ рдПрдХ рд╣реА рдХреЙрд▓рдо рдХреЗ рд╕рд╛рде рдПрдХ рдкрд╛рдВрдбрд╛ рдбреЗрдЯрд╛ рдлреНрд░реЗрдо рд╣реИ рд▓реЗрдХрд┐рди рдЕрджреНрдпрддрди рдорд╛рди рд╣реИрдВ:

| рдЖрдИрдбреА | рдирд╛рдо |
| --- | --- |
| 0 | рдХреНрд░рд┐рд╕ |
| 1 | рдЬреЗрдореНрд╕ |

рдЖрдЗрдП рдпрд╣ рднреА рдорд╛рди рд▓реЗрдВ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдбреЗрдЯрд╛рдмреЗрд╕ рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рддреНрд░ рдЪрд░ рдЦреБрд▓рд╛ рд╣реИред рдЗрд╕ рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдХреЗ:

session.bulk_update_mappings(
User,
<pandas dataframe above>.to_dict(orient='records')
)

рдкрд╛рдВрдбрд╛ рдЯреЗрдмрд▓ рдХреЛ рд╢рдмреНрджрдХреЛрд╢реЛрдВ рдХреА рд╕реВрдЪреА рдореЗрдВ рдмрджрд▓ рджреЗрдВрдЧреЗ [{id: 0, name: "chris"}, {id: 1, name:"james"}] рдЬрд┐рд╕рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ sql рдЯреЗрдмрд▓ рдХреА рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░реЗрдЧрд╛ред рддреЛ рдЕрдВрддрд┐рдо рддрд╛рд▓рд┐рдХрд╛ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦреЗрдЧреА:

| рдЖрдИрдбреА | рдирд╛рдо |
| --- | --- |
| 0 | рдХреНрд░рд┐рд╕ |
| 1 | рдЬреЗрдореНрд╕ |
| 2 | рд╣реИрд░реА |

рдирдорд╕реНрддреЗ, @ danich1 рдФрд░ рдЖрдкрдХреА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд-рдмрд╣реБрдд рдзрдиреНрдпрд╡рд╛рджред рдореИрдВрдиреЗ рдЦреБрдж рдХреЛ рдпрд╛рдВрддреНрд░рд┐рдХреА рд╕рдордЭ рд▓рд┐рдпрд╛ рдХрд┐ рдЕрдкрдбреЗрдЯ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░реЗрдЧрд╛ред рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ рдореБрдЭреЗ рдирд╣реАрдВ рдкрддрд╛ рдХрд┐ рд╕рддреНрд░ рдХреЗ рд╕рд╛рде рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рдирд╛ рд╣реИ, рдореИрдВ рдХрд╛рдлреА рд╢реБрд░реБрдЖрдд рдХрд░ рд░рд╣рд╛ рд╣реВрдВред

рдореИрдВ рдЖрдкрдХреЛ рджрд┐рдЦрд╛рддрд╛ рд╣реВрдВ рдХрд┐ рдореИрдВ рдХреНрдпрд╛ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ:

`рдЖрдпрд╛рдд pypyodbc
to_sql_newrows рд╕реЗ clean_df_db_dups рдЖрдпрд╛рдд рдХрд░реЗрдВ, to_sql_newrows # рдпреЗ 2 рдлрд╝рдВрдХреНрд╢рди рд╣реИрдВ рдЬреЛ рдореБрдЭреЗ GitHub рдкрд░ рдорд┐рд▓реЗ, рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ рдореБрдЭреЗ рд▓рд┐рдВрдХ рдпрд╛рдж рдирд╣реАрдВ рд╣реИред Clean_df_db_dups рдПрдХ рдбреЗрдЯрд╛рдлрд╝реНрд░реЗрдо рд╕реЗ рдЙрди рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреЛ рдмрд╛рд╣рд░ рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА SQL рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдХрдИ рдкреНрд░рдореБрдЦ рд╕реНрддрдВрднреЛрдВ рдХреА рдЬрд╛рдБрдЪ рдХрд░рдХреЗ рдореМрдЬреВрдж рд╣реИрдВ рдФрд░ to_sql_newrows рдПрдХ рдРрд╕рд╛ рдлрд╝рдВрдХреНрд╢рди рд╣реИ рдЬреЛ sql рдореЗрдВ рдирдИ рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреЛ рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░рддрд╛ рд╣реИред

from sqlalchemy import create_engine
engine = create_engine("engine_connection_string")

#Write data to SQL
Tablename = 'Dummy_Table_Name'
Tablekeys = Tablekeys_string
dftoupdateorinsertinSQL= random_dummy_dataframe

#Connect to sql server db using pypyodbc
cnxn = pypyodbc.connect("Driver={SQL Server};"
                        "Server=ServerName;"
                        "Database=DatabaseName;"
                        "uid=userid;pwd=password")

newrowsdf= clean_df_db_dups(dftoupdateorinsertinSQL, Tablename, engine, dup_cols=Tablekeys)
newrowsdf.to_sql(Tablename, engine, if_exists='append', index=False, chunksize = 140)
end=timer()

tablesize = (len(newrowsdf.index))

print('inserted %r rows '%(tablesize))`

рдЙрдкрд░реЛрдХреНрдд рдХреЛрдб рдореВрд▓ рд░реВрдк рд╕реЗ рдЙрди рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреЛ рдбреЗрдЯрд╛рдлреНрд░реЗрдо рд╕реЗ рдмрд╛рд╣рд░ рдХрд░ рд░рд╣рд╛ рд╣реИ рдЬреЛ рдореЗрд░реЗ рдкрд╛рд╕ рдкрд╣рд▓реЗ рд╕реЗ SQL рдореЗрдВ рд╣реИрдВ рдФрд░ рдХреЗрд╡рд▓ рдирдИ рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреЛ рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░рддрд╛ рд╣реИред рдореБрдЭреЗ рдЬреЛ рдЪрд╛рд╣рд┐рдП рд╡рд╣ рдореМрдЬреВрдж рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреЛ рдЕрджреНрдпрддрди рдХрд░рдирд╛ рд╣реИред рдХреНрдпрд╛ рдЖрдк рдХреГрдкрдпрд╛ рдореБрдЭреЗ рдпрд╣ рд╕рдордЭрдиреЗ рдореЗрдВ рдорджрдж рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдореБрдЭреЗ рдЖрдЧреЗ рдХреНрдпрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП?

рдПрдХ рдмреЗрд╣рддрд░ TO_SQL рдХреЗ рд▓рд┐рдП рдкреНрд░реЗрд░рдгрд╛
to_sql рдбреЗрдЯрд╛рдмреЗрд╕ рдкреНрд░рдерд╛рдУрдВ рдХреЗ рд╕рд╛рде рдмреЗрд╣рддрд░ рдПрдХреАрдХрд░рдг рдХрд╛ рдорд╣рддреНрд╡ рдмрдврд╝ рд░рд╣рд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдбреЗрдЯрд╛ рд╡рд┐рдЬреНрдЮрд╛рди рдмрдврд╝рддрд╛ рд╣реИ рдФрд░ рдбреЗрдЯрд╛ рдЗрдВрдЬреАрдирд┐рдпрд░рд┐рдВрдЧ рдХреЗ рд╕рд╛рде рдорд┐рд╢реНрд░рд┐рдд рд╣реЛ рдЬрд╛рддрд╛ рд╣реИред

upsert рдЙрдирдореЗрдВ рд╕реЗ рдПрдХ рд╣реИ, рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдХреНрдпреЛрдВрдХрд┐ рдмрд╣реБрдд рд╕реЗ рд▓реЛрдЧ рдкрд╛рддреЗ рд╣реИрдВ рдХрд┐ рдЗрд╕рдХреЗ рдмрдЬрд╛рдп replace рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реИ, рдЬреЛ рддрд╛рд▓рд┐рдХрд╛ рдХреЛ рдЫреЛрдбрд╝ рджреЗрддрд╛ рд╣реИ, рдФрд░ рдЗрд╕рдХреЗ рд╕рд╛рде рд╕рднреА рд╡рд┐рдЪрд╛рд░ рдФрд░ рдмрд╛рдзрд╛рдПрдВ рд╣реИрдВред

рдЕрдзрд┐рдХ рдЕрдиреБрднрд╡реА рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдореЗрдВ рдореИрдВрдиреЗ рдЬреЛ рд╡рд┐рдХрд▓реНрдк рджреЗрдЦрд╛ рд╣реИ, рд╡рд╣ рдЗрд╕ рд╕реНрддрд░ рдкрд░ рдкрд╛рдВрдбрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдмрдВрдж рдХрд░рдирд╛ рд╣реИ, рдФрд░ рдпрд╣ рдЕрдкрд╕реНрдЯреНрд░реАрдо рдХрд╛ рдкреНрд░рдЪрд╛рд░ рдХрд░рддрд╛ рд╣реИ рдФрд░ рдкрд╛рдВрдбрд╛ рдкреИрдХреЗрдЬ рдХреЛ рдЕрдиреБрднрд╡реА рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЗ рдмреАрдЪ рдвреАрд▓рд╛ рд░рдЦрддрд╛ рд╣реИред рдХреНрдпрд╛ рдпрд╣реА рд╡рд╣ рджрд┐рд╢рд╛ рд╣реИ рдЬрд╣рд╛рдВ рдкрдВрдбреЛрдВ рдЬрд╛рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ?

рдореИрдВ рд╕рдордЭрддрд╛ рд╣реВрдВ рдХрд┐ рд╣рдо рдЬрд┐рддрдирд╛ рд╕рдВрднрд╡ рд╣реЛ рд╕рдХреЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдЕрдЬреНрдЮреЗрдпрд╡рд╛рджреА рдмрдиреЗ рд░рд╣рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдФрд░ рдХреЛрд░ рдПрд╕рдХреНрдпреВрдПрд▓ рдХреАрдорд┐рдпрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред рдПрдХ рд╡рд┐рдзрд┐ рдЬреЛ рдПрдХ рд╕рдЪреНрдЪреЗ рдЕрдкреНрд╕рд░реНрдЯ рдХреЗ рдмрдЬрд╛рдп рдХрд╛рдЯ-рдЫрд╛рдБрдЯ рдпрд╛ рд╣рдЯрд╛ рджреЗрддреА рд╣реИ, рдлрд┐рд░ рднреА рдмрд╣реБрдд рдЕрдзрд┐рдХ рдореВрд▓реНрдп рдЬреЛрдбрд╝ рджреЗрдЧреАред

рдкрд╛рдВрдбрд╛ рдЙрддреНрдкрд╛рдж рджреГрд╖реНрдЯрд┐ рдХреЗ рд╕рд╛рде рдПрдХреАрдХрд░рдг
рдЙрдкрд░реЛрдХреНрдд рдмрд╣реБрдд рд╕реА рдмрд╣рд╕ method рддрд░реНрдХ (рдЬреИрд╕рд╛ рдХрд┐ @kjford рджреНрд╡рд╛рд░рд╛ psql_insert_copy рд╕рд╛рде рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ) рдФрд░ рдПрдХ рдХреЙрд▓ рдХрд░рдиреЗ рдпреЛрдЧреНрдп рдкрд░ рдкрд╛рд░рд┐рдд рд╣реЛрдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рд╕реЗ рдкрд╣рд▓реЗ рд╣реБрдИ рдереАред

рдореИрдВ рдЦреБрд╢реА рд╕реЗ рдпрд╛ рддреЛ рдореВрд▓ рдкрд╛рдВрдбрд╛ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдореЗрдВ рдпреЛрдЧрджрд╛рди рджреЗрддрд╛ рд╣реВрдВ, рдпрд╛ рдЕрд╕рдлрд▓ рд░рд╣рд╛ рд╣реВрдВ, рдкрдВрдбреЛрдВ рдХреЗ рднреАрддрд░ рдПрдХ рдКрдкрд░реА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЗ рдкрд░ рд╕рдорд╛рдзрд╛рди/рд╕рд░реНрд╡реЛрддреНрддрдо рдЕрднреНрдпрд╛рд╕ рдкрд░ рджрд╕реНрддрд╛рд╡реЗрдЬ, рдЬреИрд╕реЗ рдХрд┐ рдиреАрдЪреЗ:
https://pandas.pydata.org/pandas-docs/stable/user_guide/io.html#io -sql-method

рдкрдВрдбреЛрдВ рдХреЗ рдХреЛрд░ рджреЗрд╡ / рдЙрддреНрдкрд╛рдж рдкреНрд░рдмрдВрдзрдХреЛрдВ рдХреЗ рд▓рд┐рдП рдкрд╕рдВрджреАрджрд╛ рддрд░реАрдХрд╛ рдХреНрдпрд╛ рд╣реИ?

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╣рдо рдПрдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдП рдЦреБрд▓реЗ рд╣реИрдВ рдЬреЛ рдЗрдВрдЬрди-рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╣реИред method='upsert' рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рдЙрдЪрд┐рдд рд▓рдЧрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕ рдмрд┐рдВрджреБ рдкрд░ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╣рдореЗрдВ рд╕реНрдкрд╖реНрдЯ рдбрд┐рдЬрд╛рдЗрди рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЗ рд╕рд╛рде рдЖрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рд╕реА рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

рдореЗрд░реЗ рдкрд╛рд╕ рдПрдХ рд╕рдорд╛рди рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬрд╣рд╛рдВ рдореИрдВ рд╕рдордп рдХреЗ рд╕рд╛рде рдПрдХрд╛рдзрд┐рдХ рд╕реАрдПрд╕рд╡реА рд╕реЗ рдПрдХ MySQL рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдореМрдЬреВрджрд╛ рдбреЗрдЯрд╛ рдЕрдкрдбреЗрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред

рдореИрдВрдиреЗ рд╕реЛрдЪрд╛ рдХрд┐ рдореИрдВ рдПрдХ рдирдИ рдмрдирд╛рдИ рдЧрдИ рдЕрд╕реНрдерд╛рдпреА рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдирдпрд╛ рдбреЗрдЯрд╛ рдбрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП df.to_sql() рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ рдФрд░ рдлрд┐рд░ рдореМрдЬреВрджрд╛ рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдбреЗрдЯрд╛ рдХреЛ рдЬреЛрдбрд╝рдиреЗ/рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреЗ рддрд░реАрдХреЗ рдХреЛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ MySQL рдХреНрд╡реЗрд░реА рдЪрд▓рд╛ рд╕рдХрддрд╛ рд╣реВрдВред

MySQL рд╕рдВрджрд░реНрдн: https://stackoverflow.com/questions/2472229/insert-into-select-from-on-duplicate-key-update?answertab=active#tab -top

рдЕрд╕реНрд╡реАрдХрд░рдг: рдореИрдВрдиреЗ рдХреБрдЫ рджрд┐рди рдкрд╣рд▓реЗ рд╣реА рдкрд╛рдпрдерди рдФрд░ рдкрдВрдбреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд┐рдпрд╛ рдерд╛ред

рд╣реЗ рдкрдВрдбреЛрдВ рдХреЗ рд▓реЛрдЧ: рдореЗрд░реЗ рдкрд╛рд╕ рднреА рдпрд╣реА рдореБрджреНрджрд╛ рд╣реИ, рдореБрдЭреЗ рдЕрдкрдиреЗ рд╕реНрдерд╛рдиреАрдп рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рд░рд┐рдХреЙрд░реНрдб рдХреЗ рд╕рд╛рде рдмрд╛рд░-рдмрд╛рд░ рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдореИрдВ рдЕрдВрддрддрдГ рдкрдВрдбреЛрдВ рдореЗрдВ рд▓реЛрдб рдФрд░ рд╣реЗрд░рдлреЗрд░ рдХрд░рддрд╛ рд╣реВрдВред рдореИрдВрдиреЗ рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рд╛рдзрд╛рд░рдг рдкреБрд╕реНрддрдХрд╛рд▓рдп рдмрдирд╛рдпрд╛ - рдпрд╣ рдореВрд▓ рд░реВрдк рд╕реЗ df.to_sql рдФрд░ pd.read_sql_table рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реНрдЯреИрдВрдб-рдЗрди рд╣реИ рдЬреЛ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдкреНрд░рд╛рдердорд┐рдХ рдХреБрдВрдЬреА рдХреЗ рд░реВрдк рдореЗрдВ рдбреЗрдЯрд╛рдлрд╝реНрд░реЗрдо рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдХреЗрд╡рд▓ sqlalchemy рдХреЛрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред

https://pypi.org/project/pandabase/0.2.1/
Https://github.com/notsambeck/pandabase

рдпрд╣ рдЙрдкрдХрд░рдг рдХрд╛рдлреА рд░рд╛рдп рд╡рд╛рд▓рд╛ рд╣реИ, рд╢рд╛рдпрдж рдкрдВрдбреЛрдВ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рдирд╣реАрдВ рд╣реИред рд▓реЗрдХрд┐рди рдореЗрд░реЗ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдпрд╣ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рддрд╛ рд╣реИ ... рдЕрдЧрд░ рдЗрд╕реЗ рдкрдВрдбреЛрдВ рдореЗрдВ рдлрд┐рдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдорд╛рд▓рд┐рд╢ рдХрд░рдиреЗ рдореЗрдВ рд░реБрдЪрд┐ рд╣реИ рддреЛ рдореБрдЭреЗ рдорджрдж рдХрд░рдиреЗ рдореЗрдВ рдЦреБрд╢реА рд╣реЛрдЧреАред

рдЕрднреА рдХреЗ рд▓рд┐рдП, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрд╛рд░реНрдп (рд╡рд░реНрддрдорд╛рди-рдИрд╢ рдкрд╛рдВрдбрд╛ рдФрд░ рд╕реНрдХреНрд▓реЗрд▓реНрдХреЗрдореА рдХреЗ рд╕реАрдорд┐рдд рдорд╛рдорд▓реЗ рдореЗрдВ, рдкреНрд░рд╛рдердорд┐рдХ рдХреБрдВрдЬреА рдХреЗ рд░реВрдк рдореЗрдВ рдирд╛рдорд┐рдд рдЕрдиреБрдХреНрд░рдордгрд┐рдХрд╛, SQLite рдпрд╛ рдкреЛрд╕реНрдЯрдЧреНрд░реЗрд╕ рдмреИрдХ рдПрдВрдб, рдФрд░ рд╕рдорд░реНрдерд┐рдд рдбреЗрдЯрд╛рдЯрд╛рдЗрдк):

рдкрд╛рдЗрдк рд╕реНрдерд╛рдкрд┐рдд рдкрд╛рдВрдбрд╛рдмреЗрд╕ / pandabase.to_sql (df, table_name, con_string, рдХреИрд╕реЗ = 'рдЕрдкрд╕рд░реНрдЯ')

cvonsteg рдХреЗ рд╕рд╛рде рдЗрд╕рдХреЗ рд╕рд╛рдорд╛рдиреНрдп рд╕рдорд╛рдзрд╛рди рдкрд░ рдХрд╛рд░реНрдп рдХрд░рдирд╛ред рдЕрдХреНрдЯреВрдмрд░ рдореЗрдВ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рдбрд┐рдЬрд╛рдЗрди рдХреЗ рд╕рд╛рде рд╡рд╛рдкрд╕ рдЖрдиреЗ рдХреА рдпреЛрдЬрдирд╛ рд╣реИред

@TomAugspurger рдЬреИрд╕рд╛ рдХрд┐ рд╕реБрдЭрд╛рд╡ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, @rugg2 рдФрд░ рдореИрдВ upsert рдореЗрдВ to_sql() upsert рд╡рд┐рдХрд▓реНрдк рдХреЗ рд▓рд┐рдП рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдбрд┐рдЬрд╝рд╛рдЗрди рдкреНрд░рд╕реНрддрд╛рд╡ рд▓реЗрдХрд░ рдЖрдП рд╣реИрдВред

рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдкреНрд░рд╕реНрддрд╛рд╡

to_sql() рд╡рд┐рдзрд┐ рдореЗрдВ рд╕рдВрднрд╛рд╡рд┐рдд method рддрд░реНрдХ рдХреЗ рд░реВрдк рдореЗрдВ рдЬреЛрдбрд╝реЗ рдЬрд╛рдиреЗ рд╡рд╛рд▓реЗ 2 рдирдП рдЪрд░:
1) upsert_update - рдкрдВрдХреНрддрд┐ рдорд┐рд▓рд╛рди рдкрд░, рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдЕрджреНрдпрддрди рдкрдВрдХреНрддрд┐ (рдЬрд╛рдирдмреВрдЭрдХрд░ рд░рд┐рдХреЙрд░реНрдб рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП - рдЕрдзрд┐рдХрд╛рдВрд╢ рдЙрдкрдпреЛрдЧ рдорд╛рдорд▓реЛрдВ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддрд╛ рд╣реИ)
2) upsert_ignore - рдкрдВрдХреНрддрд┐ рдорд┐рд▓рд╛рди рдкрд░, рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдкрдВрдХреНрддрд┐ рдХреЛ рдЕрдкрдбреЗрдЯ рди рдХрд░реЗрдВ (рдЙрди рдорд╛рдорд▓реЛрдВ рдХреЗ рд▓рд┐рдП рдЬрд╣рд╛рдВ рдбреЗрдЯрд╛рд╕реЗрдЯ рдУрд╡рд░рд▓реИрдк рд╣реИрдВ, рдФрд░ рдЖрдк рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдореЗрдВ рдбреЗрдЯрд╛ рдХреЛ рдУрд╡рд░рд░рд╛рдЗрдб рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ)

import pandas as pd
from sqlalchemy import create_engine

engine = create_engine("connection string")
df = pd.DataFrame(...)

df.to_sql(
    name='table_name', 
    con=engine, 
    if_exists='append', 
    method='upsert_update' # (or upsert_ignore)
)

рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкреНрд░рд╕реНрддрд╛рд╡

рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, SQLTable рд╡рд░реНрдЧ рдХреЛ рдЕрдкреНрд╕рд░реНрдЯ рд▓реЙрдЬрд┐рдХ рд╡рд╛рд▓реА 2 рдирдИ рдирд┐рдЬреА рд╡рд┐рдзрд┐рдпрд╛рдВ рдкреНрд░рд╛рдкреНрдд рд╣реЛрдВрдЧреА, рдЬрд┐рдиреНрд╣реЗрдВ SQLTable.insert() рд╡рд┐рдзрд┐ рд╕реЗ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛:

def insert(self, chunksize=None, method=None):

    #set insert method
    if method is None:
        exec_insert = self._execute_insert
    elif method == "multi":
        exec_insert = self.execute_insert_multi
    #new upsert methods <<<
    elif method == "upsert_update":
        exec_insert = self.execute_upsert_update
    elif method == "upsert_ignore":
        exec_insert = self.execute_upsert_ignore
    # >>>
    elif callable(method):
        exec_inset = partial(method, self)
    else:
        raise ValueError("Invalid parameter 'method': {}".format(method))

    ...

рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рдХрд░рддреЗ рд╣реИрдВ, рдиреАрдЪреЗ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдЙрд▓реНрд▓рд┐рдЦрд┐рдд рддрд░реНрдХ рдХреЗ рд╕рд╛рде (рд╕рднреА рдмрд┐рдВрджреБ рдЪрд░реНрдЪрд╛ рдХреЗ рд▓рд┐рдП рдЦреБрд▓реЗ рд╣реИрдВ):

(1) DELETE рдФрд░ INSERT рдкрд░рдорд╛рдгреБ рдЕрдиреБрдХреНрд░рдо рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ SQLAlchemy рдХреЛрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рдЗрдВрдЬрди рдЕрдЬреНрдЮреЗрдпрд╡рд╛рджреА

  • рдХреЗрд╡рд▓ рдХреБрдЫ рдбреАрдмреАрдПрдордПрд╕ рдореВрд▓ рд░реВрдк рд╕реЗ upsert рд╕рдорд░реНрдерди рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╕реНрд╡рд╛рджреЛрдВ рдореЗрдВ рднрд┐рдиреНрди рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ
  • рдкрд╣рд▓реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд░реВрдк рдореЗрдВ рд╣рдо рдорд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рд╕рднреА рдбреАрдмреАрдПрдордПрд╕ рдореЗрдВ рдПрдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛ рдкрд░реАрдХреНрд╖рдг рдФрд░ рд░рдЦрд░рдЦрд╛рд╡ рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реЛрдЧрд╛ред рднрд╡рд┐рд╖реНрдп рдореЗрдВ, рдпрджрд┐ рдорд╛рдВрдЧ рдореМрдЬреВрдж рд╣реИ, рддреЛ рдЗрдВрдЬрди-рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдЬреЛрдбрд╝рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
  • upsert_ignore рдЗрди рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдорд┐рд▓рд╛рди рд░рд┐рдХреЙрд░реНрдб рдкрд░ рдЫреЛрдбрд╝ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛
  • рдкреНрд░рджрд░реНрд╢рди рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдЗрдВрдЬрди-рдЕрдЬреНрдЮреЗрдп рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдмрдирд╛рдо рдЗрдВрдЬрди-рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рддреБрд▓рдирд╛ рдХрд░рдирд╛ рдЙрдЪрд┐рдд рд╣реЛрдЧрд╛ред

(реи) рдХреЗрд╡рд▓ рдкреНрд░рд╛рдердорд┐рдХ рдХреБрдВрдЬреА рдкрд░ рдЕрдкреНрд╕рд░реНрдЯ рдХрд░реЗрдВ

  • рдЬрдм рддрдХ рдЕрдиреНрдпрдерд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддрдм рддрдХ рдкреНрд░рд╛рдердорд┐рдХ рдХреБрдВрдЬреА рдХреНрд▓реИрд╢ рдХреЗ рд▓рд┐рдП рдЕрдкреНрд╕рд░реНрдЯ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд╣реЛрддреЗ рд╣реИрдВ
  • рдХреБрдЫ рдбреАрдмреАрдПрдордПрд╕ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рдЧреИрд░-рдкреНрд░рд╛рдердорд┐рдХ-рдХреБрдВрдЬреА рдХреЙрд▓рдо рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХреЗ рд╡рд┐рд░реБрджреНрдз рд╡рд┐рд╢рд┐рд╖реНрдЯрддрд╛ рдХреА рдЬрд╛рдВрдЪ рдХреА рдЬрд╛рддреА рд╣реИред рдЬрдмрдХрд┐ рдпрд╣ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдЕрдзрд┐рдХ рд▓рдЪреАрд▓рд╛рдкрди рджреЗрддрд╛ рд╣реИ, рдпрд╣ рд╕рдВрднрд╛рд╡рд┐рдд рдиреБрдХрд╕рд╛рди рдХреЗ рд╕рд╛рде рдЖрддрд╛ рд╣реИред рдпрджрд┐ рдЗрди рд╕реНрддрдВрднреЛрдВ рдореЗрдВ UNIQUE рдмрд╛рдзрд╛ рдирд╣реАрдВ рд╣реИ, рддреЛ рдпрд╣ рд╕рдВрднрд╡ рд╣реИ рдХрд┐ рдХрдИ рдкрдВрдХреНрддрд┐рдпрд╛рдБ рдКрдкрд░реА рд╕реНрдерд┐рддрд┐ рд╕реЗ рдореЗрд▓ рдЦрд╛ рд╕рдХрддреА рд╣реИрдВред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдХреЛрдИ рдЕрдкрд░рд░реНрдЯ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдЕрд╕реНрдкрд╖реНрдЯ рд╣реИ рдХрд┐ рдХрд┐рд╕ рд░рд┐рдХреЙрд░реНрдб рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдкрд╛рдВрдбрд╛ рд╕реЗ рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдкреНрд░рддреНрдпреЗрдХ рдкрдВрдХреНрддрд┐ рдХреЛ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ рдореВрд▓реНрдпрд╛рдВрдХрди рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА рддрд╛рдХрд┐ рдпрд╣ рдЬрд╛рдВрдЪрд╛ рдЬрд╛ рд╕рдХреЗ рдХрд┐ рдХреЗрд╡рд▓ 1 рдпрд╛ 0 рдкрдВрдХреНрддрд┐рдпрд╛рдВ рдбрд╛рд▓рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдореЗрд▓ рдЦрд╛рддреА рд╣реИрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдпрдереЛрдЪрд┐рдд рд░реВрдк рд╕реЗ рд╕рд░рд▓ рд╣реИ, рдЗрд╕рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рдкреНрд░рддреНрдпреЗрдХ рд░рд┐рдХреЙрд░реНрдб рдХреЛ рдкрдврд╝рдиреЗ рдФрд░ рд▓рд┐рдЦрдиреЗ рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ (рд╕рд╛рде рд╣реА рдЕрдЧрд░ 1 рд░рд┐рдХреЙрд░реНрдб рдХреНрд▓реИрд╢ рдкрд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рддреЛ рдбрд┐рд▓реАрдЯ), рдЬреЛ рдмрдбрд╝реЗ рдбреЗрдЯрд╛рд╕реЗрдЯ рдХреЗ рд▓рд┐рдП рдЕрддреНрдпрдзрд┐рдХ рдЕрдХреНрд╖рдо рд▓рдЧрддрд╛ рд╣реИред
  • рднрд╡рд┐рд╖реНрдп рдХреЗ рд╕реБрдзрд╛рд░ рдореЗрдВ, рдпрджрд┐ рд╕рдореБрджрд╛рдп рдЗрд╕рдХреЗ рд▓рд┐рдП рдХрд╣рддрд╛ рд╣реИ, рддреЛ рд╣рдо рди рдХреЗрд╡рд▓ рдкреНрд░рд╛рдердорд┐рдХ рдХреБрдВрдЬреА рдкрд░ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдмрд▓реНрдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХреНрд╖реЗрддреНрд░реЛрдВ рдкрд░ рднреА рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкреНрд╕рд░реНрдЯ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред рдХреЛрд░-рджреЗрд╡ рдЯреАрдо рдХреЗ рд▓рд┐рдП рдпрд╣ рдПрдХ рджреАрд░реНрдШрдХрд╛рд▓рд┐рдХ рдкреНрд░рд╢реНрди рд╣реИ, рдХрд┐ рдХреНрдпрд╛ рдкрдВрдбреЛрдВ рдХреЛ рдЙрди рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреА рд╕реБрд░рдХреНрд╖рд╛ рдХреЗ рд▓рд┐рдП рд╕рд░рд▓ рд░рд╣рдирд╛ рдЪрд╛рд╣рд┐рдП рдЬрд┐рдирдХреЗ рдкрд╛рд╕ рдЦрд░рд╛рдм рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рдбреЗрдЯрд╛рдмреЗрд╕ рд╣реИ, рдпрд╛ рдЕрдзрд┐рдХ рдХрд╛рд░реНрдпрд╛рддреНрдордХрддрд╛рдПрдВ рд╣реИрдВред

@TomAugspurger, рдЕрдЧрд░ upsert рдкреНрд░рд╕реНрддрд╛рд╡ рд╕реВрдЯ рдЖрдк @cvonsteg рдХреЗ рд╕рд╛рде рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд╣рдо рдХреЛрдб рдореЗрдВ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди (inclред рдкрд░реАрдХреНрд╖рдг) рдХреЗ рд╕рд╛рде рдЖрдЧреЗ рдмрдврд╝рдирд╛ рдФрд░ рдПрдХ рдкреБрд▓ рдЕрдиреБрд░реЛрдз рдХреЛ рдмрдврд╝рд╛ рджреЗрдВрдЧреЗред

рдЕрдЧрд░ рдЖрдк рдЕрд▓рдЧ рддрд░реАрдХреЗ рд╕реЗ рдЖрдЧреЗ рдмрдврд╝рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рддреЛ рд╣рдореЗрдВ рдмрддрд╛рдПрдВред

рдкреНрд░рд╕реНрддрд╛рд╡ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкрдврд╝рдирд╛ рдореЗрд░реА рдЯреВрдбреВ рд╕реВрдЪреА рдореЗрдВ рд╣реИред рдореИрдВ рдЕрдкрдиреЗ рдкрд░ рдереЛрдбрд╝рд╛ рдкреАрдЫреЗ рд╣реВрдБ
рдЕрднреА рдИрдореЗрд▓ рдХрд░реЗрдВред

рдмреБрдзрд╡рд╛рд░, 9 рдЕрдХреНрдЯреВрдмрд░, 2019 рдХреЛ рд╕реБрдмрд╣ 9:18 рдмрдЬреЗ рд░реЛрдореЗрди рдиреЛрдЯрд┐рдлрд┐рдХреЗрд╢рди @github.com рдиреЗ рд▓рд┐рдЦрд╛:

@TomAugspurger https://github.com/TomAugspurger , рдЕрдЧрд░ рдбрд┐рдЬрд╛рдЗрди рд╣рдо
@cvonsteg https://github.com/cvonsteg рдХреЗ рд╕рд╛рде рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рдЖрдк рдкрд░ рд╕реВрдЯ рдХрд░рддрд╛ рд╣реИ, рд╣рдо рдХрд░реЗрдВрдЧреЗ
рдХреЛрдб рдореЗрдВ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд╕рд╛рде рдЖрдЧреЗ рдмрдврд╝реЗрдВ (рдкрд░реАрдХреНрд╖рдг рд╕рд╣рд┐рдд) рдФрд░ рдПрдХ рдкреБрд▓ рдмрдврд╝рд╛рдПрдВ
рдкреНрд░рд╛рд░реНрдердирд╛ред

рдЕрдЧрд░ рдЖрдк рдЕрд▓рдЧ рддрд░реАрдХреЗ рд╕реЗ рдЖрдЧреЗ рдмрдврд╝рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рддреЛ рд╣рдореЗрдВ рдмрддрд╛рдПрдВред

-
рдЖрдк рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ рдЖрдкрдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред
рдЗрд╕ рдИрдореЗрд▓ рдХрд╛ рд╕реАрдзреЗ рдЙрддреНрддрд░ рджреЗрдВ, рдЗрд╕реЗ GitHub рдкрд░ рджреЗрдЦреЗрдВ
https://github.com/pandas-dev/pandas/issues/14553?email_source=notifications&email_token=AAKAOITBNTWOQRBW3OWDEZDQNXR25A5CNFSM4CU2M7O2YY3PNVWWK3TUL52HS4DFVREXGEA43VMVBW63LNMVW-5K2K7LNMVWXH
рдпрд╛ рдереНрд░реЗрдб рдХреЛ рдореНрдпреВрдЯ рдХрд░реЗрдВ
https://github.com/notifications/unsubscribe-auth/AAKAOIRZQEQWUY36PQ36QTLQNXR25ANCNFSM4CU2M7OQ
.

рдореЗрд░реЗ рдкрд╛рд╕ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ рдЗрд╕рдХреЗ рдЦрд┐рд▓рд╛рдл рдХреБрдЫ рднреА рдирд╣реАрдВ рд╣реИ рдЗрд╕рд▓рд┐рдП рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдПрдХ рдкреАрдЖрд░ рдХрд╛ рд╕реНрд╡рд╛рдЧрдд рд╣реИред SQLAlchemy рдХреЛрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рд╕рднреА DBMs рдореЗрдВ рдПрдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдпрд╣ рдХреИрд╕реЗ рд╢реБрд░реВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдпрджрд┐ рдореИрдВ рдЖрдкрдХреЗ рдмрд┐рдВрджреБрдУрдВ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдкрдврд╝ рд░рд╣рд╛ рд╣реВрдВ, рдФрд░ рдХреЗрд╡рд▓ рдкреНрд░рд╛рдердорд┐рдХ рдХреБрдВрдЬреА рдХреЗ рд╕рд╛рдеред

рдЫреЛрдЯреЗ рдФрд░ рдХреЗрдВрджреНрд░рд┐рдд рд╢реБрд░реБрдЖрдд рдХрд░рдирд╛ рдФрд░ рд╡рд╣рд╛рдВ рд╕реЗ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдирд╛ рд╣рдореЗрд╢рд╛ рдЖрд╕рд╛рди рд╣реЛрддрд╛ рд╣реИ

рдЗрд╕ рд╕реБрд╡рд┐рдзрд╛ рдХреА рд╕рдЦреНрдд рдЬрд░реВрд░рдд рд╣реИред

рдкреАрдЖрд░ рд╣рдордиреЗ cvonsteg рдХреЗ рд╕рд╛рде рд▓рд┐рдЦрд╛ рдерд╛ рдЕрдм рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рджреЗрдирд╛ рдЪрд╛рд╣рд┐рдП: рдЕрдм рд╕рдореАрдХреНрд╖рд╛ рдХреЗ рд▓рд┐рдП рдиреАрдЪреЗ!

рдпрд╣ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдмрд┐рд▓реНрдХреБрд▓ рд╢рд╛рдирджрд╛рд░ рд╣реЛрдЧреА! рдореИрдВ рдЬреАрдердм рдХреА рд╢рдмреНрджрд╛рд╡рд▓реА рдореЗрдВ рдмрд╣реБрдд рдкрд╛рд░рдВрдЧрдд рдирд╣реАрдВ рд╣реВрдБ; рдХреНрдпрд╛ @ Rugg2 рджреНрд╡рд╛рд░рд╛ рдЯрд┐рдкреНрдкрдгреА рдХреА рдЧрдИ рд╣реИ рдХрд┐ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ "рдЕрдм рд╕рдореАрдХреНрд╖рд╛ рдХреЗ рд▓рд┐рдП рдиреАрдЪреЗ рд╣реИ" рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдпрд╣ рдкрд╛рдВрдбрд╛ рдЯреАрдо рдХреА рд╕рдореАрдХреНрд╖рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдиреАрдЪреЗ рд╣реИ? рдФрд░ рдЕрдЧрд░ рдпрд╣ рд╕реНрд╡реАрдХреГрдд рд╣реИ, рддреЛ рдХреНрдпрд╛ рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣ рдкрд╛рдВрдбрд╛ рдХреЗ рдПрдХ рдирдП рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЙрдкрд▓рдмреНрдз рд╣реЛ рдЬрд╛рдПрдЧрд╛ рдЬрд┐рд╕реЗ рд╣рдо рд╕реНрдерд╛рдкрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╛ рдХреНрдпрд╛ рд╣рдореЗрдВ рдЧрд┐рдЯ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ рдкреНрд░рддрд┐рдмрджреНрдзрддрд╛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА? (рдореБрдЭреЗ рдЗрд╕рдХреЗ рд╕рд╛рде рдХреЛрдВрдбрд╛ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕рдорд╕реНрдпрд╛рдПрдВ рдЖрдИ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдпрджрд┐ рдРрд╕рд╛ рд╣реИ рддреЛ рдореИрдВ рдЗрд╕ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЗ рддреИрдпрд╛рд░ рд╣реЛрдиреЗ рддрдХ рдЧрддрд┐ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ)ред рд╢реБрдХреНрд░рд┐рдпрд╛!!

@ pmgh2345 - рд╣рд╛рдБ, рдЬреИрд╕рд╛ рдХрд┐ рдЖрдкрдиреЗ рдХрд╣рд╛, "рдЕрдм рд╕рдореАрдХреНрд╖рд╛ рдХреЗ рд▓рд┐рдП рдиреАрдЪреЗ" рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдПрдХ рдкреБрд▓ рдЕрдиреБрд░реЛрдз рдЙрдард╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдФрд░ рдореВрд▓ рджреЗрд╡реЛрдВ рдХреА рд╕рдореАрдХреНрд╖рд╛ рдХреЗ рдЕрдзреАрди рд╣реИред рдЖрдк рдКрдкрд░ рдЙрд▓реНрд▓рд┐рдЦрд┐рдд рдкреАрдЖрд░ (#29636) рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВред рдПрдХ рдмрд╛рд░ рдпрд╣ рд╕реНрд╡реАрдХреГрдд рд╣реЛ рдЬрд╛рдиреЗ рдХреЗ рдмрд╛рдж, рдЖрдк рддрдХрдиреАрдХреА рд░реВрдк рд╕реЗ рдЕрджреНрдпрддрди рдХреЛрдб рдХреЗ рд╕рд╛рде рд╢рд╛рдЦрд╛ рдХреЛ рдлреЛрд░реНрдХ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдкрд╛рдВрдбрд╛ рдХреЗ рдЕрдкрдиреЗ рд╕реНрдерд╛рдиреАрдп рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЗ рд╕рд╛рде рд╕рдВрдХрд▓рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдореИрдВ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд░реВрдк рд╕реЗ рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░рдиреЗ рдХреА рдЕрдиреБрд╢рдВрд╕рд╛ рдХрд░рддрд╛ рд╣реВрдВ рдЬрдм рддрдХ рдХрд┐ рдЗрд╕реЗ рдорд╛рд╕реНрдЯрд░ рдореЗрдВ рд╡рд┐рд▓рдп рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЬрд╛рд░реА рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рдмрд╕ рдкрд╛рдЗрдк рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдирд╛ рдкрд╛рдВрдбрд╛ рдХрд╛ рдирд╡реАрдирддрдо рд╕рдВрд╕реНрдХрд░рдгред

рдкреАрдЖрд░ рд╣рдордиреЗ cvonsteg рдХреЗ рд╕рд╛рде рд▓рд┐рдЦрд╛ рдерд╛ рдЕрдм рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рджреЗрдирд╛ рдЪрд╛рд╣рд┐рдП: рдЕрдм рд╕рдореАрдХреНрд╖рд╛ рдХреЗ рд▓рд┐рдП рдиреАрдЪреЗ!

if_exists рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдмрдЬрд╛рдп to_sql рд╡рд┐рдзрд┐ рдореЗрдВ рдПрдХ рдирдпрд╛ рдкреИрд░рд╛рдореАрдЯрд░ рдЬреЛрдбрд╝рдирд╛ рдЙрдЪрд┐рдд рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдХрд╛рд░рдг, if_exists рддрд╛рд▓рд┐рдХрд╛ рдХреА рдЬрд╛рдВрдЪ рдХрд░ рд░рд╣рд╛ рд╣реИ, рдкрдВрдХреНрддрд┐ рдирд╣реАрдВ, рдЕрд╕реНрддрд┐рддреНрд╡ред

@cvonsteg рдореВрд▓ рд░реВрдк рд╕реЗ method= рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ , рдЬреЛ if_exists рджреЛ рдЕрд░реНрде рд╣реЛрдиреЗ рдХреА рдЕрд╕реНрдкрд╖реНрдЯрддрд╛ рд╕реЗ рдмрдЪ рдЬрд╛рдПрдЧрд╛ред

df.to_sql(
    name='table_name', 
    con=engine, 
    if_exists='append', 
    method='upsert_update' # (or upsert_ignore)
)

@brylie рд╣рдо рдПрдХ рдирдпрд╛ рдкреИрд░рд╛рдореАрдЯрд░ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ рд╕рдЪ рд╣реИ, рд▓реЗрдХрд┐рди рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдирдпрд╛ рдкреИрд░рд╛рдореАрдЯрд░ рдПрдХ рдПрдкреАрдЖрдИ рдХреЛ рдФрд░ рдЕрдзрд┐рдХ

рдпрджрд┐ рд╣рдореЗрдВ рд╡рд░реНрддрдорд╛рди рдорд╛рдкрджрдВрдбреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХреЛ рдЪреБрдирдирд╛ рд╣реИ, рдЬреИрд╕рд╛ рдХрд┐ рдЖрдкрдиреЗ рдХрд╣рд╛ рдерд╛ рдХрд┐ рд╣рдордиреЗ рд╢реБрд░реВ рдореЗрдВ method рддрд░реНрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрд╛ рдерд╛, рд▓реЗрдХрд┐рди рдЕрдзрд┐рдХ рд╡рд┐рдЪрд╛рд░реЛрдВ рдХреЗ рдмрд╛рдж рд╣рдордиреЗ рдорд╣рд╕реВрд╕ рдХрд┐рдпрд╛ рдХрд┐ рджреЛрдиреЛрдВ (1) рдЙрдкрдпреЛрдЧ рдФрд░ (2) рддрд░реНрдХ рдмреЗрд╣рддрд░ рд░реВрдк рд╕реЗ if_exists рддрд░реНрдХред

1) рдПрдкреАрдЖрдИ рдЙрдкрдпреЛрдЧ рдХреЗ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╕реЗ
рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдПрдХ рддрд░рдл рд╡рд┐рдзрд┐ = "рдмрд╣реБ" рдпрд╛ рдХреЛрдИ рдирд╣реАрдВ, рдФрд░ рджреВрд╕рд░реА рддрд░рдл "рдЕрдкреНрд╕рд░реНрдЯ" рджреЛрдиреЛрдВ рдХреЛ рдЪреБрдирдирд╛ рдЪрд╛рд╣реЗрдЧрд╛ред рд╣рд╛рд▓рд╛рдВрдХрд┐, "рдЕрдкреНрд╕рд░реНрдЯ" рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд╕рд╛рде рд╕рдорд╛рди рд░реВрдк рд╕реЗ рдордЬрдмреВрдд рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЗ рдирд╣реАрдВ рд╣реИрдВ рдЬреИрд╕реЗ рдХрд┐ if_exists="append" рдпрд╛ "replace", рдпрджрд┐ рдХреЛрдИ рд╣реЛред

2) рддрд░реНрдХ рдХреА рджреГрд╖реНрдЯрд┐ рд╕реЗ

  • рд╡рд┐рдзрд┐ рд╡рд░реНрддрдорд╛рди рдореЗрдВ _how_ рдкрд░ рдХрд╛рдо рдХрд░рддреА рд╣реИ, рдбреЗрдЯрд╛ рдбрд╛рд▓рд╛ рдЬрд╛ рд░рд╣рд╛ рд╣реИ: рдкрдВрдХреНрддрд┐ рд╕реЗ рдкрдВрдХреНрддрд┐ рдпрд╛ "рдмрд╣реБ"
  • if_exists рд╣рдо рдЕрдкрдиреЗ рд░рд┐рдХреЙрд░реНрдб рдХреЛ рдХреИрд╕реЗ рдкреНрд░рдмрдВрдзрд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕рдХреЗ рд╡реНрдпрд╛рд╡рд╕рд╛рдпрд┐рдХ рддрд░реНрдХ рдХреЛ рдХреИрдкреНрдЪрд░ рдХрд░рддрд╛ рд╣реИ: "рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ", "рд╕рдВрд▓рдЧреНрди рдХрд░реЗрдВ", "рдЕрдкрд╕рд░реНрдЯ_рдЕрдкрдбреЗрдЯ" (рдХреБрдВрдЬреА рдореМрдЬреВрдж рд╣реЛрдиреЗ рдкрд░ рдЕрдкреНрд╕рд░реНрдЯ рдХрд░реЗрдВ, рдирдпрд╛ рд╣реЛрдиреЗ рдкрд░ рд╕рдВрд▓рдЧреНрди рдХрд░реЗрдВ), "рдЕрдкреНрд╕рд░реНрдЯ_рдЗрдЧреНрдиреЛрд░" (рдХреБрдВрдЬреА рдореМрдЬреВрдж рд╣реЛрдиреЗ рдкрд░ рдЕрдирджреЗрдЦрд╛ рдХрд░реЗрдВ, рдирдпрд╛ рд╣реЛрдиреЗ рдкрд░ рд╕рдВрд▓рдЧреНрди рдХрд░реЗрдВ)ред рд╣рд╛рд▓рд╛рдВрдХрд┐ рд░рд┐рдкреНрд▓реЗрд╕ рдФрд░ рдПрдкреЗрдВрдб рдЯреЗрдмрд▓ рдХреЗ рдЕрд╕реНрддрд┐рддреНрд╡ рдХреЛ рджреЗрдЦ рд░рд╣реЗ рд╣реИрдВ, рдЗрд╕реЗ рд░рд┐рдХреЙрд░реНрдб рд╕реНрддрд░ рдкрд░ рдЗрд╕рдХреЗ рдкреНрд░рднрд╛рд╡ рд╕реЗ рднреА рд╕рдордЭрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред

рдореБрдЭреЗ рдмрддрд╛рдПрдВ рдХрд┐ рдХреНрдпрд╛ рдореИрдВ рдЖрдкрдХреА рдмрд╛рдд рдХреЛ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рд╕рдордЭрддрд╛ рд╣реВрдВ, рдФрд░ рдХреГрдкрдпрд╛ рдЪрд┐рд▓реНрд▓рд╛рдПрдВ рдпрджрд┐ рдЖрдкрдХреЛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╕рдореАрдХреНрд╖рд╛ рдХреЗ рддрд╣рдд рд╡рд░реНрддрдорд╛рди рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди (рдкреАрдЖрд░ # 29636) рд╢реБрджреНрдз рдирдХрд╛рд░рд╛рддреНрдордХ рд╣реЛрдЧрд╛!

рд╣рд╛рдБ, рдЖрдк рдореЗрд░реА рдмрд╛рдд рд╕рдордЭрддреЗ рд╣реИрдВред рд╡рд░реНрддрдорд╛рди рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдПрдХ рд╢реБрджреНрдз рд╕рдХрд╛рд░рд╛рддреНрдордХ рд╣реИ рд▓реЗрдХрд┐рди рдЕрд╕реНрдкрд╖реНрдЯ рд╢рдмреНрджрд╛рд░реНрде рд╕реЗ рдереЛрдбрд╝рд╛ рдХрдо рд╣реИред

рдореИрдВ рдЕрднреА рднреА рдпрд╣ рдорд╛рдирддрд╛ рд╣реВрдВ рдХрд┐ if_exists рдХреЗрд╡рд▓ рдПрдХ рдЪреАрдЬ, рдЯреЗрдмрд▓ рдЕрд╕реНрддрд┐рддреНрд╡ рдХреЛ рд╕рдВрджрд░реНрднрд┐рдд рдХрд░рдирд╛ рдЬрд╛рд░реА рд░рдЦрдирд╛ рдЪрд╛рд╣рд┐рдПред рдорд╛рдкрджрдВрдбреЛрдВ рдореЗрдВ рдЕрд╕реНрдкрд╖реНрдЯрддрд╛ рд╣реЛрдиреЗ рд╕реЗ рдкрдардиреАрдпрддрд╛ рдкрд░ рдирдХрд╛рд░рд╛рддреНрдордХ рдкреНрд░рднрд╛рд╡ рдкрдбрд╝рддрд╛ рд╣реИ, рдФрд░ рдЬрдЯрд┐рд▓ рдЖрдВрддрд░рд┐рдХ рддрд░реНрдХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдЬрдмрдХрд┐, рдПрдХ рдирдпрд╛ рдкреИрд░рд╛рдореАрдЯрд░ рдЬреЛрдбрд╝рдирд╛, рдЬреИрд╕реЗ upsert=True рд╕реНрдкрд╖реНрдЯ рдФрд░ рд╕реНрдкрд╖реНрдЯ рд╣реИред

рдирдорд╕реНрдХрд╛рд░!

рдпрджрд┐ рдЖрдк рдЕрдкреНрд╕рд░реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЧреИрд░ рдЕрдЬреНрдЮреЗрдп рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рджреЗрдЦрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рддреЛ рдореЗрд░реЗ рдкрд╛рд╕ рдореЗрд░реА рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдкреИрдВрдЧреНрд░реЗрд╕ рдХреЗ рд╕рд╛рде рдПрдХ рдЙрджрд╛рд╣рд░рдг рд╣реИред рдпрд╣ рдЙрди рдбреЗрдЯрд╛рдмреЗрд╕ рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢рд┐рд╖реНрдЯ sqlalchemy рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ PostgreSQL рдФрд░ MySQL рдХреЛ рд╕рдВрднрд╛рд▓рддрд╛ рд╣реИред SQlite рдХреЗ рд▓рд┐рдП (рдФрд░ рдЕрдиреНрдп рдбреЗрдЯрд╛рдмреЗрд╕ рдкреНрд░рдХрд╛рд░ рдПрдХ рд╕рдорд╛рди рдЕрдкрд░рд░реНрдЯ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВ) рдпрд╣ рдПрдХ рд╕рдВрдХрд▓рд┐рдд рдирд┐рдпрдорд┐рдд sqlalchemy рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░реЗрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред

рдореИрдВ рдЗрд╕ рд╕реЛрдЪ рдХреЛ рд╕рд╛рдЭрд╛ рдХрд░рддрд╛ рд╣реВрдВ рдХрд┐ рдпрд╣ рд╕рд╣рдпреЛрдЧрд┐рдпреЛрдВ рдХреЛ рдХреБрдЫ рд╡рд┐рдЪрд╛рд░ рджреЗ рд╕рдХрддрд╛ рд╣реИ (рд╣рд╛рд▓рд╛рдВрдХрд┐ рдореБрдЭреЗ рдкрддрд╛ рд╣реИ рдХрд┐ рд╣рдо рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ SQL рдкреНрд░рдХрд╛рд░ рдЕрдЬреНрдЮреЗрдпрд╡рд╛рджреА рд╣реЛ рдЬреЛ рдмрд╣реБрдд рд╕рдордЭ рдореЗрдВ рдЖрддрд╛ рд╣реИ)ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛ рд╢рд╛рдпрдж рдЧрддрд┐ рдХреА рддреБрд▓рдирд╛ рднреА рджрд┐рд▓рдЪрд╕реНрдк рд╣реЛрдЧреА рдЬрдм @cvonsteg рдХрд╛ рдкреАрдЖрд░ рдЧреБрдЬрд░рддрд╛ рд╣реИред
рдХреГрдкрдпрд╛ рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдореИрдВ рд▓рдВрдмреЗ рд╕рдордп рд╕реЗ sqlalchemy рд╡рд┐рд╢реЗрд╖рдЬреНрдЮ рдпрд╛ рдРрд╕рд╛ рдирд╣реАрдВ рд╣реВрдВ!

рдореИрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдпрд╣ рд╕реБрд╡рд┐рдзрд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред рдореИрдВ рд╕рд╣рдордд рд╣реВрдВ рдХрд┐ method='upsert_update' рдПрдХ рдЕрдЪреНрдЫрд╛ рд╡рд┐рдЪрд╛рд░ рд╣реИред

рдХреНрдпрд╛ рдпрд╣ рдЕрднреА рднреА рдпреЛрдЬрдирд╛рдмрджреНрдз рд╣реИ? рдкрдВрдбреЛрдВ рдХреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЗрд╕ рд╕реБрд╡рд┐рдзрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ

рд╣рд╛рдБ рдпрд╣ рдЕрднреА рднреА рдпреЛрдЬрдирд╛рдмрджреНрдз рд╣реИ, рдФрд░ рд╣рдо рд▓рдЧрднрдЧ рд╡рд╣рд╛рдБ рд╣реИрдВ!

рдХреЛрдб рд▓рд┐рдЦрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХ рдкрд░реАрдХреНрд╖рд╛ рд╣реИ рдЬреЛ рдкрд╛рд╕ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИред рдорджрдж рдХрд╛ рд╕реНрд╡рд╛рдЧрдд рдХрд┐рдпрд╛!
https://github.com/pandas-dev/pandas/pull/29636

рдордВрдЧрд▓рд╡рд╛рд░, 5 рдордИ, 2020, 19:18 рдХреЛ рд▓рд┐рдпреЛрдиреЗрд▓ рдПрдЯреЗрдВрд╕рд┐рдпреЛ рдиреЛрдЯрд┐рдлрд┐рдХреЗрд╢рди @github.com рдиреЗ рд▓рд┐рдЦрд╛:

рдХреНрдпрд╛ рдпрд╣ рдЕрднреА рднреА рдпреЛрдЬрдирд╛рдмрджреНрдз рд╣реИ? рдкрдВрдбреЛрдВ рдХреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЗрд╕ рд╕реБрд╡рд┐рдзрд╛ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ

-
рдЖрдк рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд░рд╣реЗ рд╣реИрдВ рдХреНрдпреЛрдВрдХрд┐ рдЖрдкрдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред
рдЗрд╕ рдИрдореЗрд▓ рдХрд╛ рд╕реАрдзреЗ рдЙрддреНрддрд░ рджреЗрдВ, рдЗрд╕реЗ GitHub рдкрд░ рджреЗрдЦреЗрдВ
https://github.com/pandas-dev/pandas/issues/14553#issuecomment-624223231 ,
рдпрд╛ рд╕рджрд╕реНрдпрддрд╛ рд╕рдорд╛рдкреНрдд рдХрд░реЗрдВ
https://github.com/notifications/unsubscribe-auth/AI5X625A742YTYFZE7YW5A3RQBJ6NANCNFSM4CU2M7OQ
.

рдирдорд╕реНрдХрд╛рд░! рдХреНрдпрд╛ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рддреИрдпрд╛рд░ рд╣реИ рдпрд╛ рдХреБрдЫ рдЕрднреА рднреА рдЧрд╛рдпрдм рд╣реИ? рдЕрдЧрд░ рдЕрднреА рднреА рдХреБрдЫ рдЫреВрдЯ рдЧрдпрд╛ рд╣реИ, рддреЛ рдХреГрдкрдпрд╛ рдореБрдЭреЗ рдмрддрд╛рдПрдВ рдХрд┐ рдХреНрдпрд╛ рдореИрдВ рдХреБрдЫ рдорджрдж рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ!

рдХреЛрдИ рдЦрдмрд░?))

рдЬрд╛рд╡рд╛ рджреБрдирд┐рдпрд╛ рд╕реЗ рдЖ рд░рд╣рд╛ рд╣реИ, рдХрднреА рдирд╣реАрдВ рд╕реЛрдЪрд╛ рдерд╛ рдХрд┐ рдпрд╣ рд╕рд░рд▓ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдореЗрд░реЗ рдХреЛрдбрдмреЗрд╕ рдХреЛ рдЙрд▓реНрдЯрд╛ рдХрд░ рд╕рдХрддреА рд╣реИред

рд╣реЗрд▓реЛ рд╕рдм рд▓реЛрдЧ,

рдореИрдВрдиреЗ рджреЗрдЦрд╛ рд╣реИ рдХрд┐ рдПрд╕рдХреНрдпреВрдПрд▓ рдореЗрдВ рдмреЛрд▓рд┐рдпреЛрдВ рдореЗрдВ рдЕрдкреНрд╕рд░реНрдЯ рдХреИрд╕реЗ рд▓рд╛рдЧреВ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ рдФрд░ рдХрдИ рддрдХрдиреАрдХреЗрдВ рдорд┐рд▓рддреА рд╣реИрдВ рдЬреЛ рдпрд╣рд╛рдВ рдбрд┐рдЬрд╛рдЗрди рдирд┐рд░реНрдгрдпреЛрдВ рдХреЛ рд╕реВрдЪрд┐рдд рдХрд░ рд╕рдХрддреА рд╣реИрдВред рд▓реЗрдХрд┐рди рдкрд╣рд▓реЗ, рдореИрдВ DELETE ... INSERT рддрд░реНрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдЦрд┐рд▓рд╛рдл рдЪреЗрддрд╛рд╡рдиреА рджреЗрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред рдпрджрд┐ рд╡рд┐рджреЗрд╢реА рдХреБрдВрдЬреА рдпрд╛ рдЯреНрд░рд┐рдЧрд░ рд╣реИрдВ, рддреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдЕрдиреНрдп рд░рд┐рдХреЙрд░реНрдб рдирд╖реНрдЯ рд╣реЛ рдЬрд╛рдПрдВрдЧреЗ рдпрд╛ рдЕрдиреНрдпрдерд╛ рдЧрдбрд╝рдмрдбрд╝ рд╣реЛ рдЬрд╛рдПрдВрдЧреЗред MySQL рдореЗрдВ, REPLACE рд╡рд╣реА рдиреБрдХрд╕рд╛рди рдХрд░рддрд╛ рд╣реИред рдореИрдВрдиреЗ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдбреЗрдЯрд╛ рдХреЛ рдареАрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдШрдВрдЯреЛрдВ рдХрд╛рдо рдХрд┐рдпрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдореИрдВрдиреЗ REPLACE рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рд╣реИред рддреЛ, рдЙрд╕рдиреЗ рдХрд╣рд╛, рдпрд╣рд╛рдБ SQL рдореЗрдВ рд▓рд╛рдЧреВ рдХреА рдЧрдИ рддрдХрдиреАрдХреЗрдВ рд╣реИрдВ:

рдмреЛрд▓реА | рддрдХрдиреАрдХ
-- | --
рдорд╛рдИрдПрд╕рдХреНрдпреВрдПрд▓ | рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░реЗрдВ ... рдбреБрдкреНрд▓реАрдХреЗрдЯ рдХреБрдВрдЬреА рдЕрджреНрдпрддрди рдкрд░
рдкреЛрд╕реНрдЯрдЧреНрд░реЗрдПрд╕рдХреНрдпреВрдПрд▓ | рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░реЗрдВ ... рд╕рдВрдШрд░реНрд╖ рдкрд░
SQLite | рд╕рдореНрдорд┐рд▓рд┐рдд рдХрд░реЗрдВ ... рд╕рдВрдШрд░реНрд╖ рдкрд░
рдбреАрдмреА2 | рдорд░реНрдЬ
рдПрд╕рдХреНрдпреВрдПрд▓ рд╕рд░реНрд╡рд░ | рдорд░реНрдЬ
рдУрд░реЗрдХрд▓ | рдорд░реНрдЬ
рдПрд╕рдХреНрдпреВрдПрд▓:2016 | рдорд░реНрдЬ

рдмреЗрддрд╣рд╛рд╢рд╛ рднрд┐рдиреНрди рд╡рд╛рдХреНрдп рд░рдЪрдирд╛ рдХреЗ рд╕рд╛рде, рдореИрдВ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдмреЛрд▓реА рдХреЛ рдЕрдЬреНрдЮреЗрдпрд╡рд╛рджреА рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП DELETE ... INSERT рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдкреНрд░рд▓реЛрднрди рдХреЛ рд╕рдордЭрддрд╛ рд╣реВрдВред рд▓реЗрдХрд┐рди рдПрдХ рдФрд░ рддрд░реАрдХрд╛ рд╣реИ: рд╣рдо рдПрдХ рдЕрд╕реНрдерд╛рдпреА рддрд╛рд▓рд┐рдХрд╛ рдФрд░ рдмреБрдирд┐рдпрд╛рджреА INSERT рдФрд░ UPDATE рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ MERGE рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ рдХреЗ рддрд░реНрдХ рдХрд╛ рдЕрдиреБрдХрд░рдг рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред SQL:2016 MERGE рд╕рд┐рдВрдЯреИрдХреНрд╕ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИ:

MERGE INTO target_table 
USING source_table 
ON search_condition
    WHEN MATCHED THEN
        UPDATE SET col1 = value1, col2 = value2,...
    WHEN NOT MATCHED THEN
        INSERT (col1,col2,...)
        VALUES (value1,value2,...);

Oracle рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рд╕реЗ рдЙрдзрд╛рд░ рд▓рд┐рдпрд╛ рдЧрдпрд╛
рдФрд░ SQL рд╡рд┐рдХрд┐рдмреВрдХ рдХреЗ рдЕрдиреБрд░реВрдк рд╕рдорд╛рдпреЛрдЬрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛

рдЪреВрдВрдХрд┐ SQLAlchemy рджреНрд╡рд╛рд░рд╛ рд╕рдорд░реНрдерд┐рдд рдкреНрд░рддреНрдпреЗрдХ рдмреЛрд▓реА рдЕрд╕реНрдерд╛рдпреА рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддреА рд╣реИ, рдЗрд╕рд▓рд┐рдП рдПрдХ рдЕрдкреНрд╕рд░реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реБрд░рдХреНрд╖рд┐рдд, рдмреЛрд▓реА-рдЕрдЬреНрдЮреЗрдпрд╡рд╛рджреА рджреГрд╖реНрдЯрд┐рдХреЛрдг рдПрдХ рд╣реА рд▓реЗрдирджреЗрди рдореЗрдВ рд╣реЛрдЧрд╛:

  1. рдПрдХ рдЕрд╕реНрдерд╛рдпреА рддрд╛рд▓рд┐рдХрд╛ рдмрдирд╛рдПрдБред
  2. рдЙрд╕ рдЕрд╕реНрдерд╛рдпреА рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдбреЗрдЯрд╛ рдбрд╛рд▓реЗрдВред
  3. рдПрдХ рдЕрджреНрдпрддрди рдХрд░реЗрдВ ... рд╢рд╛рдорд┐рд▓ рд╣реЛрдВред
  4. INSERT рдЬрд╣рд╛рдВ рдХреБрдВрдЬреА (рдкреНрд░рд╛рдердорд┐рдХ рдпрд╛ рдЕрджреНрд╡рд┐рддреАрдп) рдореЗрд▓ рдирд╣реАрдВ рдЦрд╛рддреАред
  5. рдЕрд╕реНрдерд╛рдпреА рддрд╛рд▓рд┐рдХрд╛ рдЧрд┐рд░рд╛рдУред

рдПрдХ рдмреЛрд▓реА-рдЕрдЬреНрдЮреЗрдп рддрдХрдиреАрдХ рд╣реЛрдиреЗ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЗрд╕рдХрд╛ рдЕрдВрддрд┐рдо рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдпрд╣ рдЪреБрдирдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдХрд░ рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рд╣реЛрдиреЗ рдХрд╛ рд▓рд╛рдн рднреА рд╣реИ рдХрд┐ рдбреЗрдЯрд╛ рдХреИрд╕реЗ рдбрд╛рд▓реЗрдВ рдпрд╛ рдХреИрд╕реЗ рдЕрдкрдбреЗрдЯ рдХрд░реЗрдВ рдФрд░ рд╕рд╛рде рд╣реА рдбреЗрдЯрд╛ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдХреМрди рд╕реА рдХреБрдВрдЬреА рд╣реИред

рдЬрдмрдХрд┐ рдЕрд╕реНрдерд╛рдпреА рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдХрд╛ рд╕рд┐рдВрдЯреИрдХреНрд╕, рдФрд░ рдЕрдкрдбреЗрдЯ рдЬреЙрдЗрди рдмреЛрд▓рд┐рдпреЛрдВ рдХреЗ рдмреАрдЪ рдереЛрдбрд╝рд╛ рднрд┐рдиреНрди рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдЙрдиреНрд╣реЗрдВ рд╣рд░ рдЬрдЧрд╣ рд╕рдорд░реНрдерд┐рдд рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред

MySQL рдХреЗ рд▓рд┐рдП рдореИрдВрдиреЗ рдЬреЛ рдЕрд╡рдзрд╛рд░рдгрд╛ рд▓рд┐рдЦреА рд╣реИ рдЙрд╕рдХрд╛ рдкреНрд░рдорд╛рдг рдиреАрдЪреЗ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:

import uuid

import pandas as pd
from sqlalchemy import create_engine


# This proof of concept uses this sample database
# https://downloads.mysql.com/docs/world.sql.zip


# Arbitrary, unique temp table name to avoid possible collision
source = str(uuid.uuid4()).split('-')[-1]

# Table we're doing our upsert against
target = 'countrylanguage'

db_url = 'mysql://<{user: }>:<{passwd: }>.@<{host: }>/<{db: }>'

df = pd.read_sql(
    f'SELECT * FROM `{target}`;',
    db_url
)

# Change for UPDATE, 5.3->5.4
df.at[0,'Percentage'] = 5.4
# Change for INSERT
df = df.append(
    {'CountryCode': 'ABW','Language': 'Arabic','IsOfficial': 'F','Percentage':0.0},
    ignore_index=True
)

# List of PRIMARY or UNIQUE keys
key = ['CountryCode','Language']

# Do all of this in a single transaction
engine = create_engine(db_url)
with engine.begin() as con:
    # Create temp table like target table to stage data for upsert
    con.execute(f'CREATE TEMPORARY TABLE `{source}` LIKE `{target}`;')
    # Insert dataframe into temp table
    df.to_sql(source,con,if_exists='append',index=False,method='multi')
    # INSERT where the key doesn't match (new rows)
    con.execute(f'''
        INSERT INTO `{target}`
        SELECT
            *
        FROM
            `{source}`
        WHERE
            (`{'`, `'.join(key)}`) NOT IN (SELECT `{'`, `'.join(key)}` FROM `{target}`);
    ''')
    # Create a doubled list of tuples of non-key columns to template the update statement
    non_key_columns = [(i,i) for i in df.columns if i not in key]
    # Whitespace for aesthetics
    whitespace = '\n\t\t\t'
    # Do an UPDATE ... JOIN to set all non-key columns of target to equal source
    con.execute(f'''
        UPDATE
            `{target}` `t`
                JOIN
            `{source}` `s` ON `t`.`{"` AND `t`.`".join(["`=`s`.`".join(i) for i in zip(key,key)])}`
        SET
            `t`.`{f"`,{whitespace}`t`.`".join(["`=`s`.`".join(i) for i in non_key_columns])}`;
    ''')
    # Drop our temp table.
    con.execute(f'DROP TABLE `{source}`;')

рдпрд╣рд╛рдБ, рдореИрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдзрд╛рд░рдгрд╛рдПрдБ рдмрдирд╛рддрд╛ рд╣реВрдБ:

  1. рдЖрдкрдХреЗ рд╕реНрд░реЛрдд рдФрд░ рдЧрдВрддрд╡реНрдп рдХреА рд╕рдВрд░рдЪрдирд╛ рд╕рдорд╛рди рд╣реИред
  2. рдХрд┐ рдЖрдк рдЕрдкрдиреЗ рдбреЗрдЯрд╛рдлреНрд░реЗрдо рдореЗрдВ рдбреЗрдЯрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рд░рд▓ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдпрд╛рдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред
  3. рдХрд┐ рдЖрдк рдЕрдкрдиреЗ рдбреЗрдЯрд╛рдлрд╝реНрд░реЗрдо рдХреЗ рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рд╕рднреА рдЧреИрд░-рдХреБрдВрдЬреА рд╕реНрддрдВрднреЛрдВ рдХреЛ рдмрд╕ рдЕрдкрдбреЗрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред
  4. рдХрд┐ рдЖрдк рдореБрдЦреНрдп рдХреЙрд▓рдо рдореЗрдВ рдбреЗрдЯрд╛ рдореЗрдВ рдХреЛрдИ рдкрд░рд┐рд╡рд░реНрддрди рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред

рдорд╛рдиреНрдпрддрд╛рдУрдВ рдХреЗ рдмрд╛рд╡рдЬреВрдж, рдореБрдЭреЗ рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдореЗрд░реА рдорд░реНрдЬ-рдкреНрд░реЗрд░рд┐рдд рддрдХрдиреАрдХ рдПрдХ рд▓рдЪреАрд▓рд╛, рдордЬрдмреВрдд рдЕрдкреНрд╕рд░реНрдЯ рд╡рд┐рдХрд▓реНрдк рдмрдирд╛рдиреЗ рдХреЗ рдкреНрд░рдпрд╛рд╕реЛрдВ рдХреЛ рд╕реВрдЪрд┐рдд рдХрд░рддреА рд╣реИред

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рдЙрдкрдпреЛрдЧреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдХрд┐рд╕реА рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреЛ рдЬреЛрдбрд╝рддреЗ рд╕рдордп рдЗрд╕ рддрд░рд╣ рдХреА рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рд╡рд┐рд╢реЗрд╖рддрд╛ рд╣реЛрдирд╛ рд╕рд╣рдЬ рд╣реИред

рдХреГрдкрдпрд╛ рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдлрд┐рд░ рд╕реЗ рд╕реЛрдЪреЗрдВ: рдореМрдЬреВрджрд╛ рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреЛ рдЬреЛрдбрд╝рдирд╛ рдмрд╣реБрдд рдЙрдкрдпреЛрдЧреА рд╣реИред
рдЕрд▓рд╛рд╕ рдкреИрдВрдЧреНрд░реЗрд╕ рдкрд╛рдпрдерди 3.7+ рддрдХ рд╕реАрдорд┐рдд рд╣реИред рдЬреИрд╕рд╛ рдХрд┐ рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ (рдореБрдЭреЗ рдкреБрд░рд╛рдиреЗ рдкрд╛рдпрдерди 3.4 рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдордЬрдмреВрд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ) рдпрд╣ рд╣рдореЗрд╢рд╛ рдПрдХ рд╡реНрдпрд╡рд╣рд╛рд░реНрдп рд╕рдорд╛рдзрд╛рди рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИред

рдзрдиреНрдпрд╡рд╛рдж, @GoldstHa - рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕рд╣рд╛рдпрдХ рдЗрдирдкреБрдЯ рд╣реИред рдореИрдВ MERGE рдЬреИрд╕реЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдП POC рдмрдирд╛рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реВрдВрдЧрд╛

DELETE/INSERT рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХреЗ рд╕рд╛рде рдореБрджреНрджреЛрдВ рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП, рдФрд░ MySQL DBs рдкрд░ @GoldstHa MERGE рджреГрд╖реНрдЯрд┐рдХреЛрдг рдкрд░ рд╕рдВрднрд╛рд╡рд┐рдд рдЕрд╡рд░реЛрдзрдХ, рдореИрдВрдиреЗ рдереЛрдбрд╝рд╛ рдФрд░ рдЦреБрджрд╛рдИ рдХреА рд╣реИред рдореИрдВрдиреЗ sqlalchemy рдЕрджреНрдпрддрди рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрд╡рдзрд╛рд░рдгрд╛ рдХреЗ рдкреНрд░рдорд╛рдг рдХреЛ рдПрдХ рд╕рд╛рде

рд╕рдВрд╢реЛрдзрд┐рдд рджреГрд╖реНрдЯрд┐рдХреЛрдг рдкреНрд░рд╕реНрддрд╛рд╡

рдПрдкреАрдЖрдИ рдХреЗ рдЖрд╕рдкрд╛рд╕ рдХреБрдЫ рдЕрдЪреНрдЫреА рдЪрд░реНрдЪрд╛рдПрдВ рд╣реБрдИ рд╣реИрдВ, рдФрд░ рдПрдХ рдЕрдкреНрд╕рд░реНрдЯ рдХреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреИрд╕реЗ рдХрд╣рд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП (рдпрд╛рдиреА if_exists рддрд░реНрдХ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ, рдпрд╛ рдПрдХ рд╕реНрдкрд╖реНрдЯ upsert рддрд░реНрдХ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ)ред рдпрд╣ рдЬрд▓реНрдж рд╣реА рд╕реНрдкрд╖реНрдЯ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдЕрднреА рдХреЗ рд▓рд┐рдП, SqlAlchemy upsert рд╕реНрдЯреЗрдЯрдореЗрдВрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░реЗрдЧреА, рдЗрд╕рдХреЗ рд▓рд┐рдП рдпрд╣ рдЫрджреНрдо рдХреЛрдб рдкреНрд░рд╕реНрддрд╛рд╡ рд╣реИ:

Identify primary key(s) and existing pkey values from DB table (if no primary key constraints identified, but upsert is called, return an error)

Make a temp copy of the incoming DataFrame

Identify records in incoming DataFrame with matching primary keys

Split temp DataFrame into records which have a primary key match, and records which don't

if upsert:
    Update the DB table using `update` for only the rows which match
else:
    Ignore rows from DataFrame with matching primary key values
finally:
    Append remaining DataFrame rows with non-matching values in the primary key column to the DB table
рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

jaradc picture jaradc  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

ericdf picture ericdf  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

hiiwave picture hiiwave  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

tade0726 picture tade0726  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

BDannowitz picture BDannowitz  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ