#python #pandas #xml #ms-access #sqlalchemy
Вопрос:
Я хотел бы спросить, я застрял в достижении максимально оптимизированной скорости с помощью этого кода. код автоматически изменяет таблицу, если он обнаружил ошибку во время запроса, пожалуйста, помогите мне провести рефакторинг этого кода для достижения наилучшего результата. В настоящее время обработка 6 файлов занимает 138 секунд, я хочу сократить ее до самых коротких, любые предложения по рефакторингу кодов приветствуются
import time
import pandas as pd
from sqlalchemy import create_engine
import msaccessdb
import sqlalchemy as sa
import sqlalchemy_access as sa_a
import pyodbc
import re
import urllib
def split_list(alist, wanted_parts=1):
length = len(alist)
return [ alist[i*length // wanted_parts: (i 1)*length // wanted_parts]
for i in range(wanted_parts) ]
def append(df,df_ne,engine,r):
df = pd.concat([df_ne, df], axis=1)
try:
df.to_sql(r,con=engine,index=False,if_exists='append')
except Exception as e:
state = True
error_log = e
while state == True:
try:
error_column = str(error_log).split('name: ')[1].split('.')[0].replace("'","")
with engine.begin() as conn:
conn.execute(sa.text(f"ALTER TABLE [{r}] ADD [{error_column}] VARCHAR(100);"))
df.to_sql(r,con=engine,index=False,if_exists='append')
state = False
except Exception as e:
error_log = e
#print(e)
error_column = str(error_log).split('name: ')[1].split('.')[0].replace("'","")
state = True
def proccess_xml(source):
#GENERATE ENGINE
connection_string = (
r'DRIVER={Microsoft Access Driver (*.mdb, *.accdb)};'
r'DBQ=C:output_generatedg.accdb;'
)
connection_uri = f"access pyodbc:///?odbc_connect={urllib.parse.quote_plus(connection_string)}"
engine = create_engine(connection_uri,echo=False)
#DF NE
xml =open(source,'r').read()
df_ne = pd.DataFrame([str(re.search('<NENAME.*?>(. ?)</NENAME>*', xml).group().replace("<NENAME>","").replace("</NENAME>",""))],columns = ['NE NAME'])
#MAIN FUNCTION
root = ET.parse(source).getroot()
for main in root:
if "syndata" in main.tag:
for object in main : #object is a class
df_shit = pd.DataFrame()
for attribute in object :
table_name = ET.QName(attribute).localname
for column in attribute:
data_value = []
data_key = []
for value in column:
if value.tag is not ET.Comment:
column_name = ET.QName(value).localname
value_name = value.text
#ITER NESTED
if len(value) != 0:
iter_value = []
iter_key = []
counter_it = 0
for it in value: #'it' is an element parent
for el in it:
if el.tag is not ET.Comment:
iter_value.append(el.text)
iter_key.append(ET.QName(el).localname)
else:
iter_value[-1] =" ".join([str(iter_value[-1])," <",el.text,">"])
counter_it = 1
value_name = " ".join([str(list(dict.fromkeys(iter_key)))," : ",str(split_list(iter_value, wanted_parts=counter_it))])
data_key.append(column_name)
data_value.append(value_name)
else:
data_value[-1] = " ".join([str(data_value[-1])," <",value.text,">"])
df = pd.DataFrame([data_value],columns = data_key)
df_shit = df_shit.append(df)
if not df_shit.empty:
append(df_shit,df_ne,engine,table_name)
start = time.time()
#ACCESS GENERATOR
msaccessdb.create(r'C:/_generated/g.accdb')
#MAIN PROCESS
proccess_xml('C:/1/CFGDATA.XML')
proccess_xml('C:/2/CFGDATA.XML')
proccess_xml('C:/3/CFGDATA.XML')
proccess_xml('C:/4/CFGDATA.XML')
proccess_xml('C:/5/CFGDATA.XML')
proccess_xml('C:/6/CFGDATA.XML')
end = time.time()
print(' TIME ELAPSED :' str(end - start)) ```
Комментарии:
1. связанные: github.com/gordthompson/sqlalchemy-access/wiki/…
2. @GordThompson спасибо!