рдорд╛рди рд▓реЗрдВ рдХрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ 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
merge
рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ ?рдореИрдВрдиреЗ рд╕рдорд╛рдзрд╛рди рдХреЗ рд╕рд╛рде рдЖрдиреЗ рдХреЗ рд▓рд┐рдП 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)
рдпрд╣ рдЕрдЪреНрдЫреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рд╣реЛрдЧреА, рд▓реЗрдХрд┐рди рдореБрдЦреНрдп рд╕рдорд╕реНрдпрд╛ рдпрд╣ рд╣реИ рдХрд┐ рд╣рдо рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рдбреЗрдЯрд╛рдмреЗрд╕-рд╕реНрд╡рд╛рдж рд╕реНрд╡рддрдВрддреНрд░ рд╣реЛ рдФрд░ рдкрдВрдбреЛрдВ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП 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))
...
рд╣рдо рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рдХрд░рддреЗ рд╣реИрдВ, рдиреАрдЪреЗ рд╡рд┐рд╕реНрддрд╛рд░ рд╕реЗ рдЙрд▓реНрд▓рд┐рдЦрд┐рдд рддрд░реНрдХ рдХреЗ рд╕рд╛рде (рд╕рднреА рдмрд┐рдВрджреБ рдЪрд░реНрдЪрд╛ рдХреЗ рд▓рд┐рдП рдЦреБрд▓реЗ рд╣реИрдВ):
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) рддрд░реНрдХ рдХреА рджреГрд╖реНрдЯрд┐ рд╕реЗ
рдореБрдЭреЗ рдмрддрд╛рдПрдВ рдХрд┐ рдХреНрдпрд╛ рдореИрдВ рдЖрдкрдХреА рдмрд╛рдд рдХреЛ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рд╕рдордЭрддрд╛ рд╣реВрдВ, рдФрд░ рдХреГрдкрдпрд╛ рдЪрд┐рд▓реНрд▓рд╛рдПрдВ рдпрджрд┐ рдЖрдкрдХреЛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╕рдореАрдХреНрд╖рд╛ рдХреЗ рддрд╣рдд рд╡рд░реНрддрдорд╛рди рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди (рдкреАрдЖрд░ # 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 рджреНрд╡рд╛рд░рд╛ рд╕рдорд░реНрдерд┐рдд рдкреНрд░рддреНрдпреЗрдХ рдмреЛрд▓реА рдЕрд╕реНрдерд╛рдпреА рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддреА рд╣реИ, рдЗрд╕рд▓рд┐рдП рдПрдХ рдЕрдкреНрд╕рд░реНрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕реБрд░рдХреНрд╖рд┐рдд, рдмреЛрд▓реА-рдЕрдЬреНрдЮреЗрдпрд╡рд╛рджреА рджреГрд╖реНрдЯрд┐рдХреЛрдг рдПрдХ рд╣реА рд▓реЗрдирджреЗрди рдореЗрдВ рд╣реЛрдЧрд╛:
рдПрдХ рдмреЛрд▓реА-рдЕрдЬреНрдЮреЗрдп рддрдХрдиреАрдХ рд╣реЛрдиреЗ рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЗрд╕рдХрд╛ рдЕрдВрддрд┐рдо рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдпрд╣ рдЪреБрдирдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдХрд░ рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рд╣реЛрдиреЗ рдХрд╛ рд▓рд╛рдн рднреА рд╣реИ рдХрд┐ рдбреЗрдЯрд╛ рдХреИрд╕реЗ рдбрд╛рд▓реЗрдВ рдпрд╛ рдХреИрд╕реЗ рдЕрдкрдбреЗрдЯ рдХрд░реЗрдВ рдФрд░ рд╕рд╛рде рд╣реА рдбреЗрдЯрд╛ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдХреМрди рд╕реА рдХреБрдВрдЬреА рд╣реИред
рдЬрдмрдХрд┐ рдЕрд╕реНрдерд╛рдпреА рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдХрд╛ рд╕рд┐рдВрдЯреИрдХреНрд╕, рдФрд░ рдЕрдкрдбреЗрдЯ рдЬреЙрдЗрди рдмреЛрд▓рд┐рдпреЛрдВ рдХреЗ рдмреАрдЪ рдереЛрдбрд╝рд╛ рднрд┐рдиреНрди рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдЙрдиреНрд╣реЗрдВ рд╣рд░ рдЬрдЧрд╣ рд╕рдорд░реНрдерд┐рдд рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред
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}`;')
рдпрд╣рд╛рдБ, рдореИрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдзрд╛рд░рдгрд╛рдПрдБ рдмрдирд╛рддрд╛ рд╣реВрдБ:
рдорд╛рдиреНрдпрддрд╛рдУрдВ рдХреЗ рдмрд╛рд╡рдЬреВрдж, рдореБрдЭреЗ рдЖрд╢рд╛ рд╣реИ рдХрд┐ рдореЗрд░реА рдорд░реНрдЬ-рдкреНрд░реЗрд░рд┐рдд рддрдХрдиреАрдХ рдПрдХ рд▓рдЪреАрд▓рд╛, рдордЬрдмреВрдд рдЕрдкреНрд╕рд░реНрдЯ рд╡рд┐рдХрд▓реНрдк рдмрдирд╛рдиреЗ рдХреЗ рдкреНрд░рдпрд╛рд╕реЛрдВ рдХреЛ рд╕реВрдЪрд┐рдд рдХрд░рддреА рд╣реИред
рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рдЙрдкрдпреЛрдЧреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдХрд┐рд╕реА рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреЛ рдЬреЛрдбрд╝рддреЗ рд╕рдордп рдЗрд╕ рддрд░рд╣ рдХреА рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рд╡рд┐рд╢реЗрд╖рддрд╛ рд╣реЛрдирд╛ рд╕рд╣рдЬ рд╣реИред
рдХреГрдкрдпрд╛ рдЗрд╕ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдлрд┐рд░ рд╕реЗ рд╕реЛрдЪреЗрдВ: рдореМрдЬреВрджрд╛ рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреЛ рдЬреЛрдбрд╝рдирд╛ рдмрд╣реБрдд рдЙрдкрдпреЛрдЧреА рд╣реИред
рдЕрд▓рд╛рд╕ рдкреИрдВрдЧреНрд░реЗрд╕ рдкрд╛рдпрдерди 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
рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА
рдЬрдмрдХрд┐
INSERT OR UPDATE
рд╕рднреА рдЗрдВрдЬрдиреЛрдВ рджреНрд╡рд╛рд░рд╛ рд╕рдорд░реНрдерд┐рдд рдирд╣реАрдВ рд╣реИ, рдбреЗрдЯрд╛рдлрд╝реНрд░реЗрдо рдЗрдВрдбреЗрдХреНрд╕ рдореЗрдВ рдкреНрд░рд╛рдердорд┐рдХ рдХреБрдВрдЬрд┐рдпреЛрдВ рдХреЗ рд╕реЗрдЯ рдХреЗ рд▓рд┐рдП рд▓рдХреНрд╖реНрдп рддрд╛рд▓рд┐рдХрд╛ рд╕реЗ рдкрдВрдХреНрддрд┐рдпреЛрдВ рдХреЛ рд╣рдЯрд╛рдХрд░ рдПрдХINSERT OR REPLACE
рдХреЛ рдЗрдВрдЬрди рдЕрдЬреНрдЮреЗрдп рдмрдирд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬрд┐рд╕рдХреЗ рдмрд╛рдж рдПрдХ рдЗрдВрд╕рд░реНрдЯ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ DataFrame рдореЗрдВ рд╕рднреА рдкрдВрдХреНрддрд┐рдпрд╛рдБред рдЖрдк рдЗрд╕реЗ рд▓реЗрди-рджреЗрди рдореЗрдВ рдХрд░рдирд╛ рдЪрд╛рд╣реЗрдВрдЧреЗред