Upsert / объединить таблицы в SQLite - PullRequest
0 голосов
/ 14 февраля 2020

Я создал базу данных, используя sqlite3 в python, которая имеет тысячи таблиц. Каждая из этих таблиц содержит тысячи строк и десять столбцов. Один из столбцов - это дата и время события: это строка в формате YYYY-mm-dd HH:MM:SS, которую я определил как первичный ключ для каждой таблицы. Время от времени я собираю новые данные (сотни строк) для каждой из этих таблиц. Каждый новый набор данных извлекается с сервера и загружается непосредственно в виде фрейма данных pandas или сохраняется в виде файла CSV. Новые данные содержат те же десять столбцов, что и мои исходные данные. Мне нужно обновить таблицы в моей базе данных, используя эти новые данные, следующим образом:

  1. Учитывая таблицу в моей базе данных, для каждой строки в новом наборе данных, если дата и время строки соответствует дате и времени существующей строки в моей базе данных, обновите оставшиеся столбцы этой строки, используя значения в новом наборе данных.
  2. Если дата и время еще не существуют, создайте новую строку и вставьте это к моей базе данных.

Ниже приведены мои вопросы:

  1. Я провел поиск в Google, и похоже, что я должен использовать UPSERT ( объединить) функциональность sqlite, но я не могу найти какие-либо примеры, показывающие, как его использовать. Есть ли фактическая команда UPSERT, и если да, может кто-нибудь привести пример (желательно с sqlite3 в Python) или указать мне полезный ресурс?
  2. Кроме того, есть ли способ сделать это так, чтобы я мог UPSERT каждый новый набор данных в свою базу данных без необходимости go строка за строкой? (Я нашел эту ссылку , которая предполагает, что это возможно, но я новичок в использовании баз данных и не уверен, как на самом деле выполнить команду UPSERT.)
  3. Может ли UPSERT также быть выполняется напрямую с использованием pandas.DataFrame.to_sql?

Мое решение для резервного копирования загружается в таблицу для UPSERTed с использованием pd.read_sql_query("SELECT * from table", con), выполняет pandas.DataFrame.merge, удаляет указанную таблицу из базы данных, а затем добавляет в обновил таблицу в базе данных, используя pd.DataFrame.to_sql (но это было бы неэффективно).

Ответы [ 2 ]

1 голос
/ 14 февраля 2020

Вместо выполнения команды upsert, почему бы вам не создать свой собственный алгоритм, который будет искать значения и заменять их, если найдены дата и время, иначе он вставит новую строку. Проверьте мой код, я написал для вас. Дайте мне знать, если вы все еще в замешательстве. Вы даже можете сделать это для множества таблиц, просто заменив имя таблицы в алгоритме какой-либо переменной и изменив его для всего списка имен таблиц.

import sqlite3
import pandas as pd

csv_data = pd.read_csv("my_CSV_file.csv")           # Your CSV Data Path

def manual_upsert():                          
    con = sqlite3.connect(connection_str)
    cur = con.cursor()
    cur.execute("SELECT * FROM my_CSV_data")        # Viewing Data from Column
    data = cur.fetchall()

    old_data_list = []                          # Collection of All Dates already in Database table.
    for line in data:
        old_data_list.append(line[0])           # I suppose you Date Column is on 0 Index.


    for new_data in csv_data:
        if new_data[0] in old_data_list:
            cur.execute("UPDATE my_CSV_data SET column1=?, column2=?, column3=? WHERE my_date_column=?",        # it will update column based on date if condition is true
                                                (new_data[1],new_data[2],new_data[3],new_data[0]))
        else:
            cur.execute("INSERT INTO my_CSV_data VALUES(?,?,?,?)",                                              # It will insert new row if date is not found.
                                                (new_data[0],new_data[1],new_data[2],new_data[3]))                 
    con.commit()
    con.close()


manual_upsert()
1 голос
/ 14 февраля 2020

Во-первых, даже если вопросы связаны, задайте их отдельно в будущем.

  1. В SQLite есть документация по обработке UPSERT , в которой описано, как использовать это, но это немного абстрактно. Вы можете проверить примеры и обсуждение здесь: SQLite - UPSERT * not * INSERT или REPLACE

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

  3. Поскольку наличие этой библиотеки предполагает to_sql не создает команды UPSERT (только INSERT).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...