J'ai un simple problème de lecture d'une feuille de calcul Excel, de traiter chaque ligne contenant environ 83 colonnes comme un enregistrement de base de données unique, de l'ajouter à l'enregistrement de datum local et finalement d'ajouter et d'écrire sur le fichier DBF.
Je peux extraire toutes les valeurs d'Excel et ajoutez-les à la liste. Mais la liste n'est pas une syntaxe correcte et je ne sais pas comment préparer / convertir la liste en enregistrement de base de données. J'utilise Openpyxl, dbf et python 3.7.
Pour le moment, je ne fais que tester et essayer de préparer les données pour la ligne 3 (d'où min_max lignes = 3)
Je comprends que les données doivent être au format (('', '', '', ... 83 entrées), \ ('', '', '', ... 83 entrées) \ )
Mais je ne sais pas comment convertir les données de la liste en enregistrement ou, alternativement, comment lire des données Excel directement dans un format DF appendable
raise TypeError("data to append must be a tuple, dict, record, or template; not a %r" % type(data)) TypeError: data to append must be a tuple, dict, record, or template; not a <class 'list'>
L'erreur se plaint de l'utilisation de la liste à ajouter à la table, et cela devrait être un enregistrement, etc. . Veuillez expliquer comment je peux convertir des lignes Excel en données de table DBF pouvant être ajoutées.
tbl_tst.open(mode=dbf.READ_WRITE) # all fields character string for everyrow in ws_IntMstDBF.iter_rows(min_row = 3, max_row = 3, max_col = ws_IntMstDBF.max_column-1): datum = [] #set([83]), will defining datum as () help solve the problem? for idx, cells in enumerate(everyrow): if cells.value is None: # for None entries, enter empty string datum.append("") continue datum.append(cells.value) # else enter cell values tbl_tst.append(datum) # append that record to table !!! list is not record error here tbl_tst.close()
3 Réponses :
Découvrez la bibliothèque Python Pandas ...
Pour lire les données d'Excel dans un dataframe Pandas, vous pouvez utiliser pandas.read_excel
Une fois la date lue dans un dataframe Pandas, vous pouvez la manipuler et ensuite l'écrire dans une base de données en utilisant pandas.DataFrame.to_sql
Voir également cette explication pour traiter la base de données io a>
Un exemple de code serait plus utile que de simples liens.
Sûr! Quel adaptateur de base de données Python utilisez-vous?
Ce n'est pas pour moi. Vous avez fourni des liens, ce qui peut être utile, mais le but de Stackoverflow est d'avoir des réponses, pas des liens vers d'autres endroits. Veuillez donc insérer un exemple de code sur la façon dont vous utiliseriez pandas.read_excel
et pandas.DataFrame.to_sql
, puis avoir les liens pour référence et étude plus approfondie.
Changez
tbl_tst.append(tuple(datum))
vers
tbl_tst.append(datum)
et cela éliminera cette erreur. Tant que toutes les données de votre cellule ont le type approprié, l'ajout devrait fonctionner.
Salut Ethan, j'ai utilisé votre suggestion et j'ai pu écrire les DBF sans problème. Le bonus supplémentaire était le fait que pyinstaller exe est entièrement fonctionnel alors que dans ma solution, pysal donnait une erreur dans l'exe généré. J'ai un problème en attente avec l'exe que les chemins relatifs tels que .. \ input \ file, etc. fonctionnent bien à partir du dossier exe mais les chemins absolus ne fonctionnent pas à moins que je ne déplace le fichier exe vers le dossier src. Est-ce une question pour un nouveau fil?
@MakJ: Oui, veuillez poser une nouvelle question pour cela. Heureux que cela fonctionne pour vous maintenant!
Merci pour les réponses, je suis allé sur un peu de tangente depuis hier soir en essayant différentes solutions.
Une solution qui a fonctionné pour moi est la suivante: Je me suis assuré que les données de la feuille de calcul que j'utilise sont toutes des chaînes / texte et j'ai converti toutes les entrées nulles en type de chaîne et saisi une chaîne vide. Donc, le code suivant effectue cette tâche:
import pandas as pd import pysal as ps import numpy as np # code from function df2dbf else: type2spec = {int: ('N', 20, 0), np.int64: ('N', 20, 0), float: ('N', 36, 15), np.float64: ('N', 36, 15), str: ('C', 200, 0) } #types = [type(df[i].iloc[0]) for i in df.columns] types = [type('C') for i in range(0, len(df.columns))] #84)] #df.columns)] #range(0,84)] # i not required, to be removed specs = [type2spec[t] for t in types] db = ps.open(dbf_path, 'w') # code continues from function df2dbf
Après avoir écrit la feuille de calcul, je l'ai rouverte à l'aide de panda dataframe et vérifié si le contenu était de type chaîne et qu'il n'y avait pas de "nan" valeurs restantes dans la trame de données. Ensuite, j'ai utilisé la fonction df2dbf de "Dani Arribas-Bel", je l'ai modifiée pour l'adapter aux données avec lesquelles je travaille et je l'ai convertie en dbf.
Le code qui importe le dataframe et le convertit au format dbf est le suivant:
abspath = Path(__file__).resolve() # resolve to relative path to absolute rootpath = abspath.parents[3] # root (my source file is3 sub directories deep xlspath = rootpath / 'sub-dir1' / 'sub-dir2' / 'sub-dir3' / 'test.xlsx' # above code is only resolving file location, ignore pd_Mst_df = pd.read_excel(xlspath) #print(pd_Mst_df) # for debug print("... Writing Master DBF file ") df2dbf(pd_Mst_df, dbfpath) # dbf path is defined similar to pd_Mst path
La fonction df2dbg utilise pysal pour écrire des dataframe au format dbf: J'ai apporté quelques modifications au code pour détecter la longueur de la ligne et les types de caractères comme suit:
#house keeping for eachrow in ws_IntMstDBF.iter_rows(min_row=2, max_row=ws_IntMstDBF.max_row, max_col=ws_IntMstDBF.max_column): for idx, cells in enumerate(eachrow): if cells.value is None: # change every Null cell type to String and put 0x20 (space) cells.data_type = 's' cells.value = " "
Le cadre de données Pandas n'a pas nécessité de modifications supplémentaires car toutes les données source étaient correctement formatées auparavant étant engagé dans un fichier Excel.
Je fournirai le lien vers pysal et df2dbf dès que je le trouverai sur stackoverflow.