Я пытаюсь создать небольшое подмножество моих больших баз данных MS SQL Server на моем локальном диске в MySQL для аналитики / ML с использованием Python. Я успешно прочитал данные в Pandas фреймах данных, преобразовал все столбцы с типом данных объекта в строку, чтобы иметь дело только со строками типа float64, int64 и bool. Затем я записываю их в MySQL, используя dataframe.to_sql
. Я использую SQLAlchemy
для создания движка, и у меня есть Mysql-python-connector
, чтобы сделать все в Python.
Проблема : при записи в локальную базу данных MySQL создаются все таблицы, но некоторые таблицы остаются пустыми, а в некоторых таблицах отсутствуют строки. Если я напишу тот же самый фрейм данных в SQLite, у меня не будет ни одной из этих проблем. Увеличение chunchsize
помогло уменьшить количество пропущенных строк, а увеличение pool_recycle
помогло уменьшить пустые таблицы, но не решило полностью ни одну из этих проблем. Особенно есть несколько конкретных c таблиц, которые никогда не заполняются. Анализ таблиц в MySQL показывает utf8mb4_0900_ai_ci
как сопоставление таблиц, что в основном означает, что он использует utf8mb4
набор символов. Таблицы не очень большие, и самое большое, что у меня есть, это менее 200К строк и 50 столбцов. Процесс не занимает много времени, менее 10 минут для чтения и записи всех 22 таблиц.
Код:
import pandas as pd
import pyodbc
import sqlalchemy
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
import mysql.connector
import gc
def update_mysql_db(local_db_name:"database filename",
tables_to_update:"lists names of all the tables and their data"):
'''Receives a list of pairs in the form of
(table name, table data in a datframe).
Creates new tables in the local database with the data provided'''
print(f"{len(tables_to_update)} tables will be updated/created")
for table in tables_to_update:
print('\n')
print(f"reading {table[0]} dataframe")
try:
table[1].to_sql(table[0].lower(),
create_engine('mysql+mysqlconnector://demo:Demo@localhost:3306/sqlalchemy',
pool_recycle=36000, echo = False),
if_exists='replace',
index='True',
chunksize=5000,
index_label ='Index')
print('Table {}.{} Created'.format(local_db_name,table[0].lower()))
except ValueError as vx:
print('Value Error : \n\n ', vx)
except Exception as ex:
print('Exception : \n\n ', ex)
gc.collect()
print('\n')
print("Finished updating the local database")
return None
def main():
Local_db = 'sqlalchemy'
update_mysql_db(Local_db,list_of_tablesnames_and_data)
gc.collect()
if __name__ == "__main__":
main()
Ошибки, которые я получаю:
reading SeminarEvaluationResponses dataframe
Exception during reset or similar
Traceback (most recent call last):
File "C:\Sam\Anaconda\lib\site-packages\sqlalchemy\pool\base.py", line 693, in _finalize_fairy
fairy._reset(pool)
File "C:\Sam\Anaconda\lib\site-packages\sqlalchemy\pool\base.py", line 880, in _reset
pool._dialect.do_rollback(self)
File "C:\Sam\Anaconda\lib\site-packages\sqlalchemy\dialects\mysql\base.py", line 2302, in do_rollback
dbapi_connection.rollback()
File "C:\Sam\Anaconda\lib\site-packages\mysql\connector\connection_cext.py", line 386, in rollback
self._cmysql.rollback()
_mysql_connector.MySQLInterfaceError: MySQL server has gone away
Exception :
MySQL server has gone away
Что еще: К сожалению, я не могу загрузить какие-либо фактические данные / базы данных / таблицы сюда, чтобы сделать код работоспособным. Я прыгаю, некоторые из вас, гуру, могут дать мне пару советов или указать мне правильное направление.