Как избежать дублирования при копировании данных из Python pandas dataframe в SQL базу данных SQLLite? - PullRequest
0 голосов
/ 04 марта 2020

Я хочу вставить pandas фрейм данных в sqltable, который я предварительно создал с использованием SQL alchemy.

Однако при этом я получаю дубликаты, так как SQLite имеет столбец индекса и когда Я копирую с фрейма данных, он использует другой индекс, и даже если данные совпадают, он может добавить его.

Подробная информация о моем статусе:

Мой pandas датафрейм не имеет иметь индекс на вставке. (index = False) Также, хотя index является первичным ключом, важны оставшиеся данные. Ни одна строка данных не должна быть дублированной, например, иметь одинаковую комбинацию содержимого для каждого из столбцов.

Моя SQL таблица создания алхимии: (из database.py)

class SQLTable(Base):
    __tablename__ = 'sqltable'
    __table_args__ = {'sqlite_autoincrement': True}
    index = Column(Integer, primary_key= True, nullable=False)
    A = Column(Integer, nullable=True)
    B  = Column(String, nullable=True)
    C  = Column(BigInteger, nullable=True)
    D  = Column(Integer, nullable=True)
    E  = Column(String, nullable=True)
    F  = Column(Float, nullable=True)

Однако, я только wi sh могу вставить в sqltable, если строка, отличная от индекса, еще не существует. Я нашел python - pandas -to sql -only-insert-new-rows однако я не знаю, как применить это к моим данным.

 df.to_sql(
     name="sqltable", 
     con=engine,
     if_exists='replace',
     index=False,
     dtype={
         'index': sqlalchemy.types.INTEGER(),
         'A': sqlalchemy.types.INTEGER(),
         'B': sqlalchemy.types.VARCHAR(length=255),
         'C': sqlalchemy.types.BIGINT(),
         'D': sqlalchemy.types.VARCHAR(length=255),
         'E': sqlalchemy.types.VARCHAR(length=255),
         'F': sqlalchemy.types.Float(precision=3, asdecimal=True)
     }
 )  

Как к go по поводу индекса? Каков наилучший способ сделать это?

Онлайн-учебник по вставке новых строк в SQL таблицу

1 Ответ

0 голосов
/ 15 марта 2020

Запишите строки панды в другую таблицу в качестве заполнителя.

import pandas as pd

col_options = dict(
    dtype={
        'index': sqlalchemy.types.INTEGER(),
        'A': sqlalchemy.types.INTEGER(),
        'B': sqlalchemy.types.VARCHAR(length=255),
        'C': sqlalchemy.types.BIGINT(),
        'D': sqlalchemy.types.VARCHAR(length=255),
        'E': sqlalchemy.types.VARCHAR(length=255),
        'F': sqlalchemy.types.Float(precision=3, asdecimal=True)
    }
)
df.to_sql(name="sqltable_temp", con=engine, if_exists='replace', index=False, **col_options)  

Извлечение только новых записей при сравнении значений в таблице заполнителей с теми значениями в таблице, в которую вы собираетесь записывать новые записи.

query = """
    SELECT A, B, C, D, E, F FROM sqltable_temp 
    EXCEPT 
    SELECT A, B, C, D, E, F FROM sqltable;
"""

new_entries = pd.read_sql(query, con=engine, **col_options)

Добавление новых записей в таблицу.

new_entries.to_sql(
    name="sqltable", con=engine, if_exists='append', **col_options)

Наконец, удалите таблицу заполнителей

engine.execute("DROP TABLE sqltable_temp;")
...