Панды to_sql - увеличить индекс таблицы при добавлении DataFrame - PullRequest
0 голосов
/ 21 февраля 2019

Я работаю над созданием продукта, который сосредотачивается на ежедневном выполнении сценария Python 3.7.0 для анализа данных.Каждый день в полночь он обрабатывает огромное количество данных, а затем экспортирует результат в две таблицы MySQL.Первая будет содержать только данные, относящиеся к текущему дню, в то время как другая таблица будет содержать объединенные данные всех выполнений.

Чтобы показать, что у меня есть, см. Код ниже, предполагая, что df будетбыть окончательным DataFrame, сгенерированным из анализа данных:

import pandas as pd
import sqlalchemy

engine = sqlalchemy.create_engine(r"mysql+pymysql://user:psswd@localhost/pathToMyDB")

df = pd.DataFrame({'Something':['a','b','c']})

df.to_sql('DReg', engine, index = True, if_exists='replace') #daily database
df.to_sql('AReg', engine, index = False, if_exists='append') #anual database

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

Итак, в первый раз, когда я сохранил df, база данных должна выглядеть так:

index   Something
0       a
1       b
2       c

И во втором моем выполнении:

index   Something
0       a
1       b
2       c
3       a
4       b
5       c

Однако,когда я установил свой индекс на True во второй команде df.to_sql (превратив его в df.to_sql('AReg', engine, index = True, if_exists='append')), после двух выполнений моя база данных выглядит так:

index   Something
0       a
1       b
2       c
0       a
1       b
2       c

Я провел некоторое исследование, ноНе удалось найти способ разрешить это автоматическое увеличение индекса.Я подумал о том, чтобы читать базу данных за каждый раз при выполнении, а затем адаптировать к ней индекс моего фрейма данных, но моя база данных может легко получить ДЕЙСТВИТЕЛЬНО большой объем, что сделает ее выполнение абсурдно медленным (а также запретил мне одновременно выполнять один и тот же анализ данных на двух компьютерах безскомпрометировать мой индекс).

Так что же является лучшим решением, чтобы этот индекс работал?Что мне здесь не хватает?

Ответы [ 2 ]

0 голосов
/ 06 мая 2019

Несмотря на то, что у Pandas есть много вариантов экспорта, его основное предназначение не предназначено для использования в качестве API управления базой данных.Управление индексами - это обычно то, о чем должна заботиться база данных.

Я бы предложил установить index=False, if_exists='append' и создать таблицу с индексом автоинкремента:

CREATE TABLE AReg (
     id INT NOT NULL AUTO_INCREMENT,
     # your fields here
     PRIMARY KEY (id)
);
0 голосов
/ 05 мая 2019

Вот мое решение.SQL + Python。 Используйте SQL для получения максимального идентификатора индекса вместо чтения всей таблицы.это быстрая и легкая нагрузка на БД и питон.В mysql мы получаем max id вручную.в Oracle мы можем получить максимальный идентификатор последовательности с помощью расширенной команды sql.

import pandas as pd
from pprint import pprint
from sqlalchemy import create_engine


db_name = 'temp'
table_name = 'tmp_table'
index_name = 'id'
mysql_url = f'mysql+mysqlconnector://root:Root123@192.168.100.200:13306/{db_name}'
engine=create_engine(mysql_url)

def to_sql_seq(df,table_name=table_name, engine=engine):

    sql_get_max_id = f'select max({index_name}) as id from {table_name}'

    max_id = pd.read_sql(sql_get_max_id, engine)[index_name][0]
    new_id_base = max_id+1
    df.index +=new_id_base
    df.index.name=index_name
    df.to_sql(table_name,engine,if_exists='append')
    return
#Check the current database record
current_table = pd.read_sql(f"select * from {table_name}",engine)
pprint(current_table)

#Simu the new data
new_data = [1,2,3,4]
new_table = pd.DataFrame(new_data,columns=['value'])
to_sql_seq(new_table)

#show the index auto_increment result
inserted_table = pd.read_sql(f'select * from {table_name}',engine)
pprint(inserted_table)

и вывод

   id  value
0   1    123
1   2    234
2   3      1
3   4      2
4   5      3
5   6      4
   id  value
0   1    123
1   2    234
2   3      1
3   4      2
4   5      3
5   6      4
6   7      1
7   8      2
8   9      3
9  10      4
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...