Вопрос Как мне добавить мой фрейм данных в базу данных, чтобы он проверял, существует ли stock_ticker, только для добавления строк, в которых stock_ticker не существует?

Это процесс, который я сделал

  1. Импортировать файл CSV в фреймворк pandas
  2. Назначьте имена столбцов такими же, как в базе данных
  3. Отправка фрейма данных в базу данных с использованием приведенного ниже кода, но получение

sqlite3.IntegrityError: UNIQUE constraint failed: stocks.stock_ticker

conn = sqlite3.connect('stockmarket.db')
c = conn.cursor()

df.to_sql(name='stocks', con=conn, if_exists='append', index=False)

conn.commit()

Я просмотрел другие случаи ошибок целостности, но не могу найти тот, который работает с добавлением фреймов данных? Я нашел и попробовал это, но все, что он делает, просто ничего не добавляет.

try:
    conn = sqlite3.connect('stockmarket.db')
    c = conn.cursor()
    df.to_sql(name='stocks', con=conn, if_exists='append', index=False)
    conn.commit()
except sqlite3.IntegrityError:
    print("Already in database")

Я не уверен, что правильно понимаю повторяющуюся вещь

Как перебирать строки в DataFrame в Pandas

Итак, я попробовал это, но он просто распечатывает уже в базе данных для каждого из них. Даже несмотря на то, что появилось 4 новых биржевых тикера.

for index, row in df.iterrows():
    try:
        conn = sqlite3.connect('stockmarket.db')
        c = conn.cursor()
        df.to_sql(name='stocks', con=conn, if_exists='append', index=False)
        conn.commit()
    except sqlite3.IntegrityError:
        print("Already in database")

enter image description here

База данных выглядит так введите здесь описание изображения

Любое понимание очень ценится :)

0
Jakub 13 Сен 2020 в 23:35

1 ответ

Лучший ответ

Похоже, это происходит из-за того, что Pandas не позволяет объявлять правильную политику ON CONFLICT на случай, если вы попытаетесь добавить данные в таблицу, которая имеет такой же (уникальный) первичный ключ или нарушает какое-то другое ограничение UNIQUEness. if_exists относится только ко всей таблице , а не к каждой отдельной строке.

Я думаю, вы уже дали довольно хороший ответ, и, возможно, с небольшой модификацией он сработает для вас:

# After connecting
for i in range(len(df)):
    try:
        df[df.index == i].to_sql(name='stocks', con=conn, if_exists='append', index=False)
        conn.commit()
    except sqlite3.IntegrityError:
        pass

Теперь это может быть проблемой, если вы действительно хотите заменить значение, если в ваших данных Pandas появляется более новое, и, допустим, вы хотите заменить старое, которое у вас есть в базе данных. В этом случае вы можете использовать необработанную команду SQL в виде строки и итеративно передавать значения Pandas. Например:

insert_statement = """
INSERT INTO stocks (stock_id,
                    stock_ticker,
                    {other columns})
VALUES (%s, %s, {as many %s as columns})
ON CONFLICT (stock_id) DO UPDATE
    SET {Define which values you will update on conflict}"""

И тогда ты мог бежать

for i in range(len(df)):
    values = tuple(df.iloc[i])
    cursor.execute(insert_statement, values)
1
tania 14 Сен 2020 в 07:00