Segnalazione #231
import csv da errore
100%
Description
octonet 0.2.2-1
octofussd 8.0.16-1
Error in test import.csv: not imported
Row number Field Error
0 username User already exists
1 username User already exists
2 username User already exists
3 username User already exists
4 username User already exists
5 username User already exists
6 username User already exists
7 username User already exists
8 username User already exists
9 username User already exists
10 username User already exists
11 username User already exists
12 username User already exists
13 username User already exists
14 username User already exists
15 username User already exists
16 username User already exists
17 username User already exists
18 username User already exists
19 username User already exists
20 username User already exists
21 username User already exists
22 username User already exists
23 username User already exists
24 username User already exists
25 username User already exists
26 username User already exists
27 username User already exists
28 username User already exists
29 username User already exists
30 username User already exists
31 username User already exists
32 username User already exists
33 username User already exists
34 username User already exists
35 username User already exists
36 username User already exists
37 username User already exists
38 username User already exists
39 username User already exists
40 username User already exists
41 username User already exists
42 username User already exists
43 username User already exists
44 username User already exists
45 username User already exists
46 username User already exists
47 username User already exists
48 username User already exists
49 username User already exists
50 username User already exists
51 username User already exists
52 username User already exists
53 username User already exists
54 username User already exists
55 username User already exists
56 username User already exists
57 username User already exists
58 username User already exists
59 username User already exists
60 username User already exists
61 username User already exists
62 username User already exists
63 username User already exists
64 username User already exists
65 username User already exists
66 username User already exists
67 username User already exists
68 username User already exists
69 username User already exists
70 username User already exists
71 username User already exists
72 username User already exists
73 username User already exists
74 username User already exists
75 username User already exists
76 username User already exists
77 username User already exists
78 username User already exists
79 username User already exists
80 username User already exists
81 username User already exists
82 username User already exists
83 username User already exists
84 username User already exists
85 username User already exists
86 username User already exists
87 username User already exists
88 username User already exists
89 username User already exists
90 username User already exists
91 username User already exists
92 username User already exists
93 username User already exists
Files
Associated revisions
Try to solve the bug. First step: StreamingHttpResponse without redirect. refs: #231
Make use of self.imported_ok. refs: #231
Send back percentage instead of . refs: #231
Draft modal window. refs: #231
Add an id to the form. refs: #231
preventDefault and show the modal. refs: #231
Fix percentage calculation. refs: #231
Disable also closing the modal via Esc keyboard button. refs: #231
Add progress bar (static for now...). refs: #231
Add CSVImportAJAX. refs: #231
Work in progress JS code for the ajax call...Not working. refs: #231
Avoid KeyError. IS IT GOOD?. refs: #231
POST also the CSV file. refs: #231
Avoid HTTP 500 when the form does not validate. Hopefully we never land here... refs: #231
Cleanup. refs: #231
Fix the percentage. refs: #231
Try to understand when/if the onprogress event is catchable... refs: #231
Comment. refs: #231
Cleanup. refs: #231
Manage the good POST: change modal title, show button and message, get redirect to user list. refs: #231
Backend rewrite to support error handling in the new AJAX powered users' CSV import. refs: #231
Javascript frontend code to somehow show the errors if they happened in the backend, during users' CSV import. refs: #231
Empty the table prior to creating the errors' rows. refs: #231
Remove the old django template code, not used anymore. refs: #231
Message does not use the filename. refs: #231
Better error message. refs: #231
Consistent CSS ids. refs: #231
Show errors. refs: #231
Check that controller group exists, as it's done with primary group. refs: #231
Add support to form errors. refs: #231
Hide and empty all error related things on load, to avoid showing unwanted things. refs: #231
This is unused. refs: #231
Massive cleanup after AJAXizing the CSV import. refs: #231
refs #231
version bump
Try to fix backend to be more resilient AND information giving... refs: #231
JS code to take care of the frontend when there is an Exception in the backend during CSV import. refs: #231
Cleanup. refs: #231
Restore the old error management and keep the new one. Best of both worlds. refs: #231
History
Updated by Christopher R. Gabriel about 7 years ago
- Assignee changed from TRUELITE to Mark Caglienzi
Updated by Christopher R. Gabriel about 7 years ago
- Status changed from Nuovo to Commenti
- Assignee changed from Mark Caglienzi to Michael Guggenberg
Solo per escludere l'ovvio, visto l'errore generato, quegli utenti non esistevano gia' quando hai provato la procedura di importazione?
Updated by Christopher R. Gabriel about 7 years ago
- Subject changed from import cvs da errore to import csv da errore
Updated by Michael Guggenberg about 7 years ago
Prtito da uno snapshot senza utenti
Creato grupp studenti, creato gruppo docenti.
Updated by Christopher R. Gabriel about 7 years ago
- Assignee changed from Michael Guggenberg to Mark Caglienzi
Ok, grazie, verifichiamo.
Updated by Michael Guggenberg about 7 years ago
la home impostata a /home/studenti/_classe_ è stata ignorata ed è stata impostata a /home/_username_
Updated by Mark Caglienzi about 7 years ago
- Status changed from In elaborazione to Commenti
- Assignee changed from Mark Caglienzi to Michael Guggenberg
Potete riprovare dopo aver aggiornato octofussd (8.0.17-1) e soprattutto octonet (0.2.3-1) ponendo l'attenzione su queste cose:
- Che gli utenti che si sta cercando di importare non esistano già (questo accade anche se si fa l'importazione due volte con lo stesso file CSV. La prima volta funziona correttamente, la seconda volta no)
- Il problema degli utenti già esistenti si può presentare anche nel caso in cui siano due persone a usare l'interfaccia: la prima che fa l'import avrà l'esito positivo, la seconda che lo fa (anche un secondo dopo) avrà l'esito negativo.
- Che le colonne siano selezionate correttamente prima di iniziare l'import (dato che l'importer cerca di fare automaticamente l'assegnamento delle colonne, ma può sbagliare)
- La home nei miei test in locale adesso viene importata correttamente (problema segnalato nel ticket)
- Non veniva importato il controller group, ora invece nei miei test in locale questo viene importato correttamente
Updated by Michael Guggenberg about 7 years ago
- File Screenshot - 04262017 - 05_08_13 PM.png Screenshot - 04262017 - 05_08_13 PM.png added
- File pre_import.ldif pre_import.ldif added
- File post_import.ldif post_import.ldif added
- File import.csv import.csv added
octonet 0.2.3-1
octofussd 8.0.17-1
Updated by Mark Caglienzi about 7 years ago
- Status changed from Commenti to In elaborazione
- Assignee changed from Michael Guggenberg to Mark Caglienzi
Questo problema è ancora diverso, sembra che ci sia stato un import parziale degli utenti e che poi la connessione si sia interrotta/resettata per qualche motivo.
Indago.
Updated by Mark Caglienzi almost 7 years ago
- Status changed from In elaborazione to Commenti
- Assignee changed from Mark Caglienzi to Christopher R. Gabriel
Rivoluzionato il backend dopo analisi con Simone e Christopher riguardo anche a octofussd (c'è un grosso problema sul numero delle connessioni create verso LDAP), e di conseguenza anche il frontend è cambiato.
9e271577:- Ora il POST del CSV è fatto via AJAX
- E' stata scritta una nuova view, e quella vecchia è diventata una
TemplateView
dato che non gestisce POST ma deve soltanto renderizzare un template, e il suo codice diform_valid()
è stato usato come base per il codice dipost()
della nuova view AJAX - La view di backend ovviamente inizia a creare gli utenti solo se il CSV non ha problemi (cioè se è stato configurato correttamente l'import rispetto alle colonne da importare, se gli utenti da importare non esistono, se i gruppi a cui aggiungere gli utenti esistono già, eccetera).
- In presenza di anche un solo errore e non viene importato nessun utente, per evitare import parziali (come era già anche prima, del resto)
- La view di backend AJAX in caso di successo invia una StreamingHttpResponse con la percentuale di utenti creati rispetto al totale degli utenti da importare
- Se tutto è ok, l'import inizia e viene mostrata una finestra modale con alcuni messaggi (è FONDAMENTALE non chiudere la finestra modale, né la finestra del browser, finché non viene dato il messaggio di importazione effettuata, altrimenti in questo caso sì che ci saranno import parziali. Il processo può impiegare davvero molti minuti, dipendentemente dal numero di utenti importati)
- La percentuale di completamento dell'import inviata via StreamingHttpResponse viene usata per aggiornare una barra di progresso nella finestra modale.
- Alla fine dell'import viene mostrato, sempre nella finestra modale, un messaggio di fine processo e un bottone che rimanda alla lista utenti, dove si potrà appurare che l'import è riuscito.
- In caso di errori la finestra modale viene nascosta e vengono mostrati gli errori, senza un reload della pagina (ma modificando il DOM via javascript).
- I messaggi di errore hanno la stessa forma che avevano prima
- Prima vengono considerati gli errori di conformità del form (ad esempio non si può chiedere di importare Full Name e uno o entrambi Name e Surname), dato che questi controlli non necessitano di LDAP
- Se il form è ok, vengono effettuati i controlli lato LDAP (gruppi non esistenti, utenti esistenti, ecc...)
- A ogni segnalazione di errore, il form resta compilato e funzionale, in questo modo è possibile fare le correzioni e procedere all'upload rapidamente (ad esempio se l'unico errore è "Gruppo non esistente", si può aprire un secondo tab in cui si crea il gruppo, poi tornare al tab dell'upload e premere Upload senza dover rifare tutta la procedura di selezione file e ordinamento colonne)
Nel frattempo sono state aggiunte alcune cose (ad esempio il controllo dell'esistenza del gruppo controller, che prima non veniva effettuato esplicitamente), e corretti alcuni particolari qua e là (typo, eccetera)
Codice pushato nel branch t231
e NON mergiato in master.
Io ho modificato il codice di octonet, il cui pacchetto quindi è da rifare.
Updated by Christopher R. Gabriel almost 7 years ago
- Assignee changed from Christopher R. Gabriel to Michael Guggenberg
Uploadati i pacchetti
- octofussd 8.0.19
- octonet 0.2.5
che includono tutto il fix della procedura di importazione.
Updated by Michael Guggenberg almost 7 years ago
- File import_1.csv import_1.csv added
- File octofussd.log octofussd.log added
L'import è sempre parziale, anche riducendo il numero degli utenti da importare.
Allego il cvs e output di octofussd.log.
root@serverfuss:~# dpkg -l octonet
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name Version Architecture Description
+++-==============-============-============-=================================
ii octonet 0.2.5-1 all OctoNet
root@serverfuss:~# dpkg -l octofussd
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name Version Architecture Description
+++-==============-============-============-=================================
ii octofussd 8.0.19-1 all server for remote computer lab ad
Updated by Christopher R. Gabriel almost 7 years ago
- Assignee changed from Michael Guggenberg to Mark Caglienzi
Updated by Christopher R. Gabriel almost 7 years ago
- Assignee changed from Mark Caglienzi to Michael Guggenberg
Michael cosa vedi nella finestra del browser? Si apre il dialog con la progress bar, poi quando si ferma? vedi errori o qualcosa del genere? Perche' guardando il log che hai allegato, si vede che non riceve piu' richieste, come se la finestra e/o il browser fossero stati chiusi, oppure si sia lasciata la pagina con il dialog della progress bar.
Updated by Michael Guggenberg almost 7 years ago
- File Screenshot - 05122017 - 10_27_49 AM.png Screenshot - 05122017 - 10_27_49 AM.png added
- File import_1.csv import_1.csv added
- File octofussd.log octofussd.log added
allego lo screenshot.
Riallego il file cvs.
Riallego octofussd.log
l'import sembra andare a buon fine, nessun errore (all users where imported!)
Updated by Christopher R. Gabriel almost 7 years ago
Ok, quindi possiamo chiudere? Cosa era successo nel tuo test precedente di diverso?
Updated by Mark Caglienzi almost 7 years ago
- La progress bar mi sembra molto corta
- Il file csv porta 200 utenti
- Il log indica 120-121 utenti importati correttamente
- Il file csv e il log sono quelli relativi all'import che sembra andato a buon fine (cioè quello dell'ultimo screenshot) ?
- Dopo aver cliccato sul bottone che porta alla lista utenti, ti ritrovi tutti gli utenti che erano presenti nel csv?
Updated by Michael Guggenberg almost 7 years ago
L'errore persiste.
octofussd.log riporta come ultimo utente create user121
2017-05-12T10:27:35+0200 [stdout#info] CREATE users/users/user121 {'uid': 'user121', 'primarygroup': 'studenti', 'homeDirectory': '/home/studenti/classe_B2011/user121
2017-05-12T10:27:35+0200 [twisted.python.log#info] 127.0.0.1 - - [12/May/2017:08:27:34 +0000] "POST /conf/ HTTP/1.1" 200 511 "-" "Python-xmlrpc/3.4"
import_1.cvs contiene 200 utenze
I file allegati corrispondono all' ultimo tentativo di importazione
Updated by Mark Caglienzi almost 7 years ago
- Status changed from Commenti to In elaborazione
- Assignee changed from Michael Guggenberg to Mark Caglienzi
Updated by Mark Caglienzi almost 7 years ago
- Aggiungere un raise forzato nel codice backend quando arriva circa a metà import
- Vedere cosa esce nei log e come si comporta la UI.
Ho aggiunto questo pezzo di codice:
if percentage >= 50: raise Exception("Ne hai già importati circa la metà")
nel metodo che crea gli utenti leggendo il CSV.
- La UI non mostra nessun errore, anzi, la modal fa vedere il messaggio di tutto ok, MA la progress bar è piena solo a metà
- Il log di octofussd non mostra nessun errore se non che smette di creare gli utenti quando arriva a metà
- Il log di django è quello che segue:
[07/Jun/2017 13:59:27] "POST /users/csvimport_ajax HTTP/1.1" 200 138 Traceback (most recent call last): File "/usr/lib/python3.5/wsgiref/handlers.py", line 138, in run self.finish_response() File "/usr/lib/python3.5/wsgiref/handlers.py", line 179, in finish_response for data in self.result: File "/home/mark/truelite/FUSS/octonet/users/views.py", line 883, in users_generator raise Exception("Ne hai già importati circa la metà") Exception: Ne hai già importati circa la metà [07/Jun/2017 13:59:27] "POST /users/csvimport_ajax HTTP/1.1" 500 59 ---------------------------------------- Exception happened during processing of request from ('127.0.0.1', 58100) Traceback (most recent call last): File "/usr/lib/python3.5/wsgiref/handlers.py", line 138, in run self.finish_response() File "/usr/lib/python3.5/wsgiref/handlers.py", line 179, in finish_response for data in self.result: File "/home/mark/truelite/FUSS/octonet/users/views.py", line 883, in users_generator raise Exception("Ne hai già importati circa la metà") Exception: Ne hai già importati circa la metà During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/usr/lib/python3.5/wsgiref/handlers.py", line 141, in run self.handle_error() File "/home/mark/truelite/FUSS/octonet/django/core/servers/basehttp.py", line 95, in handle_error super(ServerHandler, self).handle_error() File "/usr/lib/python3.5/wsgiref/handlers.py", line 368, in handle_error self.finish_response() File "/usr/lib/python3.5/wsgiref/handlers.py", line 180, in finish_response self.write(data) File "/usr/lib/python3.5/wsgiref/handlers.py", line 274, in write self.send_headers() File "/usr/lib/python3.5/wsgiref/handlers.py", line 331, in send_headers if not self.origin_server or self.client_is_modern(): File "/usr/lib/python3.5/wsgiref/handlers.py", line 344, in client_is_modern return self.environ['SERVER_PROTOCOL'].upper() != 'HTTP/0.9' TypeError: 'NoneType' object is not subscriptable During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/usr/lib/python3.5/socketserver.py", line 625, in process_request_thread self.finish_request(request, client_address) File "/usr/lib/python3.5/socketserver.py", line 354, in finish_request self.RequestHandlerClass(request, client_address, self) File "/home/mark/truelite/FUSS/octonet/django/core/servers/basehttp.py", line 102, in __init__ super(WSGIRequestHandler, self).__init__(*args, **kwargs) File "/usr/lib/python3.5/socketserver.py", line 681, in __init__ self.handle() File "/home/mark/truelite/FUSS/octonet/django/core/servers/basehttp.py", line 182, in handle handler.run(self.server.get_app()) File "/usr/lib/python3.5/wsgiref/handlers.py", line 144, in run self.close() File "/usr/lib/python3.5/wsgiref/simple_server.py", line 36, in close self.status.split(' ',1)[0], self.bytes_sent AttributeError: 'NoneType' object has no attribute 'split' ----------------------------------------
Updated by Christopher R. Gabriel almost 7 years ago
Quindi confermata la mia ipotesi. Wrappiamo il loop per intercettare l'eccezione, e restituiamo alla fine della esecuzione, prima di chiudere la connessione, l'elenco delle righe del file andate in errore, per poter informare l'utente.
Updated by Mark Caglienzi almost 7 years ago
- Assignee changed from Mark Caglienzi to Christopher R. Gabriel
Non so se così si possa fare, vista la StreamingHttpResponse.
Ho provato a wrappare la creazione e return della StreamingHttpResponse in un try, con la restituzione di una normale JsonResponse nell'except, contenente il messaggio dell'eccezione e gli utenti importati fin lì, ma non viene catchata/restituita, probabilmente perché la Streaming appena inizia a venir inviata poi impedisce di fare return di altro.
Continuo l'indagine e gli esperimenti
Updated by Christopher R. Gabriel almost 7 years ago
- Assignee changed from Christopher R. Gabriel to Mark Caglienzi
Ok, aggiornami dei risultati.
Updated by Mark Caglienzi almost 7 years ago
- Status changed from In elaborazione to Commenti
- Assignee changed from Mark Caglienzi to Christopher R. Gabriel
- Incapsulata una specie di protocollo all'interno dello streaming
- Gli errori di validazione sul form (ad es. username non scelto tra le colonne da importare) e sul CSV (ad es. utenti già esistenti) sono rimasti con la stessa gestione precedente
- Il nuovo errore (cioè l'eccezione nel backend durante l'import quando tutto il resto è ok (colonne scelte correttamente e nessun utente duplicato)) viene gestito per forza diversamente
users_generator()
è tutto dentro untry: [...] except Exception as e:
in modo che prenda su qualsiasi eccezione. In questo caso invia una stringa JSONabile contenentestatus="error"
, il testo dell'eccezione, la percentuale, e gli utenti correttamente importati fino a quel punto- Questa viene presa dal frontend, parsata in un JSON, e usata per compilare il template con un messaggio di errore che indica il problema nel backend, il testo dell'eccezione, e l'elenco degli utenti correttamente importati (così in questo modo l'utente può rimuoverli dal CSV e procedere con una nuova procedura di import, se è il caso.
- Mostrare l'elenco degli utenti non importati era più problematico
- Questo mi è sembrato (anche con il supporto di Enrico) l'unico workaround per dare una UX un pochino usabile e chiara, visto il limite intrinseco di HTTP e StreamingHTTPResponse (Una volta che la streaming inizia, dà già 200 e non si può far restituire una response diversa a quel punto).
Dai miei esperimenti/test mi pare che sia possibile fare un po' tutto: import completamente corretti, import parziali per eccezione (c'è il raise
commentato nel codice della view, se serve), prova di errori per utenti già presenti, o per errori di validazione form (cioè errori di scelta colonne da importare), anche uno di seguito all'altro (cioè provare import erronei dopo import corretti o viceversa, ecc...)
Codice pushato in t231
e non mergiato.
Updated by Christopher R. Gabriel almost 7 years ago
- Assignee changed from Christopher R. Gabriel to Michael Guggenberg
Pubblicato octonet 0.2.7 che include anche questo fix.
Updated by Michael Guggenberg almost 7 years ago
- File octofussd.log octofussd.log added
Portroppo anche dopo l'ultimo aggiornamento la situazione non è cambiata.
Provo ad importare i 200 utenti da file import_1.cvs, la statusbar non raggiunge 100%, octonet riporta di aver importato tutti gli utenti.
octofussd.log riporta 115 utenti creati e non da nessun errore.
Versioni installati:
octonet 0.2.10-1
octofuss 8.0.28-1
riallego il il file di importazione, octofussdlog
Updated by Michael Guggenberg almost 7 years ago
- Assignee changed from Michael Guggenberg to TRUELITE
Updated by Mark Caglienzi almost 7 years ago
- Status changed from Commenti to In elaborazione
- Assignee changed from TRUELITE to Mark Caglienzi
Updated by Mark Caglienzi almost 7 years ago
- File test_import.csv test_import.csv added
- Status changed from In elaborazione to Commenti
- Assignee changed from Mark Caglienzi to Michael Guggenberg
Attualmente con le versioni octofussd 8.0.30-1
e octonet 0.2.10-1
non riusciamo a riprodurre il problema, abbiamo importato il file CSV allegato a questo messaggio (con quasi 1300 utenti) senza problemi.
Updated by Paolo Dongilli almost 7 years ago
- File octofussd.log octofussd.log added
- Assignee changed from Michael Guggenberg to Mark Caglienzi
Ho fatto un test con il CSV fornito da Mark. Allego il mio octofussd.log.
Updated by Christopher R. Gabriel almost 7 years ago
- Assignee changed from Mark Caglienzi to Paolo Dongilli
Ho pubblicato nuova versione del pacchetto octonet, 0.2.13. Dopo aver riprodotto il problema, con questa soluzione non si ripresenta. Non e' un problema dell'applicazione, ma del demone che la fa girare (gunicorn).
Quando puoi, puoi verificare con questa nuova versione?
Updated by Paolo Dongilli almost 7 years ago
- Assignee changed from Paolo Dongilli to Michael Guggenberg
Ho fatto l'aggiornamento di octonet sul nostro server ed ho testato con successo l'upload di tutte le 1292 utenze dal file https://work.fuss.bz.it/attachments/download/686/test_import.csv
Il ticket per me potrebbe essere chiuso. Lo passo comunque a Michael se vuole provare a fare un test anche lui prima della chiusura definitiva.
Grazie.
Updated by Michael Guggenberg almost 7 years ago
- Assignee changed from Michael Guggenberg to TRUELITE
- % Done changed from 0 to 100
Chiudo il ticket, la problematica durante l'import non si ripresenta più.
Grazie
Use the right keys when importing. refs: #231