Forum >> Programmazione Python >> Database >> pymysql.err.ProgrammingError: (1064...

Pagina: 1 2 Avanti

Buongiorno,




sto smanettando su python e database ma mi sono imbattuto in questo errore. Non riesco a capire l'errore. Qualcuno mi da una dritta?

Il database (cassa) contiene due tabelle (causale e movimenti)





Il codice:

import pymysql.cursors

# Connessione
connection = pymysql.connect(host='localhost',
                             user='root',
                             password='123',
                             db='cassa',
                             charset='utf8mb4',
                             cursorclass=pymysql.cursors.DictCursor)
# Inserimento dati e memorizzazione variabili
datam = input("Data Movimento: ")
causale = input("Inserire 1 per Entrata e 2 per Uscita :")
descr = input("Descrizione movimento: ")
importo = input("Importo: ")

# Scrittura database
try:
    with connection.cursor() as cursor:
        sql = "INSERT INTO 'movimenti' ('DataMovimento', 'Causale', 'Descrizione', 'Importo') VALUES('" + datam + "', '" + causale + "', '" + descr + "', '" + importo + "')"
        cursor.execute(sql)
        connection.commit()

    with connection.cursor() as cursor:
        sql1 = "SELECT `DataMovimento`, `Causale`, 'Descrizione', 'Importo', 'Saldo' FROM `movimenti`"
        cursor.execute(sql1)
        result = cursor.fetchall()
        print(result)
finally:
    connection.close()
Grazie

quale errore?
THE 🍺-WARE LICENSE (Revision ㊷):
<㎝🐌🐍.🇮🇹> wrote this post. As long as you retain this notice you
can do whatever you want with this stuff. If we meet some day, and you
think this stuff is worth it, you can buy me a 🍺 in return. -- ㎝
Questo
Traceback (most recent call last):
  File "C:\Users\Utente\Desktop\Inserimento e lettura.py", line 20, in <module>
    cursor.execute(sql)
  File "C:\Users\UtenteAppData\Local\Programs\Python\Python37\lib\site-packages\pymysql\cursors.py", line 170, in execute
    result = self._query(query)
  File "C:\Users\UtenteAppData\Local\Programs\Python\Python37\lib\site-packages\pymysql\cursors.py", line 328, in _query
    conn.query(q)
  File "C:\Users\UtenteAppData\Local\Programs\Python\Python37\lib\site-packages\pymysql\connections.py", line 516, in query
    self._affected_rows = self._read_query_result(unbuffered=unbuffered)
  File "C:\Users\UtenteAppData\Local\Programs\Python\Python37\lib\site-packages\pymysql\connections.py", line 727, in _read_query_result
    result.read()
  File "C:\Users\UtenteAppData\Local\Programs\Python\Python37\lib\site-packages\pymysql\connections.py", line 1066, in read
    first_packet = self.connection._read_packet()
  File "C:\Users\UtenteAppData\Local\Programs\Python\Python37\lib\site-packages\pymysql\connections.py", line 683, in _read_packet
    packet.check_error()
  File "C:\Users\UtenteAppData\Local\Programs\Python\Python37\lib\site-packages\pymysql\protocol.py", line 220, in check_error
    err.raise_mysql_exception(self._data)
  File "C:\Users\UtenteAppData\Local\Programs\Python\Python37\lib\site-packages\pymysql\err.py", line 109, in raise_mysql_exception
    raise errorclass(errno, errval)
pymysql.err.ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''movimenti' ('DataMovimento', 'Causale', 'Descrizione', 'Importo') VALUES('1/10/' at line 1")


--- Ultima modifica di Kestrel in data 2018-10-01 18:47:54 ---
L'errore è molto esplicito, no? Il suo sql è sgrammaticato, non ti resta che vedere dove.


Naturalmente, anche senza mettermi gli occhiali per contare le virgolette, scommetto che ha qualcosa a che vedere con quell'insert. Non si compongono le query in questo modo, si usano i parametri sql.

Grazie per la dritta, ho risolto così. Accetto pareri e consigli sulla modifica a Voi esperti.




import pymysql.cursors

# Connessione
connection = pymysql.connect(host='localhost',
                             user='root',
                             password='123',
                             db='cassa',
                             charset='utf8mb4',
                             cursorclass=pymysql.cursors.DictCursor)
# Inserimento dati e memorizzazione variabili
datam = input("Data Movimento: ")
causale = input("Inserire 1 per Entrata e 2 per Uscita :")
descr = input("Descrizione movimento: ")
importo = input("Importo: ")

# Scrittura database
try:
    with connection.cursor() as cursor:
        sql = "INSERT INTO movimenti (DataMovimento, ID Causale, Descrizione, Importo) VALUES( %s, %s, %s, %s)"
        cursor.execute(sql, (datam, causale, descr, importo))
        connection.commit()

    with connection.cursor() as cursor:
        sql1 = "SELECT DataMovimento, ID Causale, Descrizione, Importo, Saldo FROM movimenti"
        cursor.execute(sql1)
        result = cursor.fetchall()
        print(result)
finally:
    connection.close()
Oltre a chiederVi consiglio sulla modifica applicata vorrei sapere come formattare le variabili che andrò ad inserire nel database. Ho riscontrato problemi sulla data (date) e Importo (sul databaseimpostato come double), perchè mi dava errore. Per farlo funzionare ho messo a tutti Varchar()




A voi possono sembrare cose banali ma a me no.

Grazie e saluti

Beh sì, adesso le query hanno le interpolazioni giuste. Tutto il resto... mah, non è codice "vero", ma suppongo che per provare qualcosa sia già sufficiente. Per quanto riguarda i tipi dei campi del database, devi leggerti la documentazione del driver che stai usando (pymysql nel tuo caso), e/o fare prove. In genere funziona così: tu dichiari il campo del database di un certo tipo (varchar, timestamp...); il driver del database dovrebbe leggere il tipo sql che hai dichiato, e convertirlo automaticamente in un corrispondente tipo python. In questo modo, per dire, tu puoi fare cose del genere:


...execute('insert into foo (mydate) values (%s);', (datetime.datetime(2018, 10, 2, 12, 40),))
e il driver converte direttamente il datetime di python in un timestamp sql. E all'inverso, un select legge i timestamp sql e ti restituisce un datetime python. E funziona per vari tipi di date, per i booleani, etc. Ma devi leggere la documentazione del driver per vedere esattamente quali sono le corrispondenze tra tipi.

Per completezza del post e per darne fruizione a tutti coloro che ne hanno bisogno posto il codice con cui ho risolto:




# Inserimento dati e memorizzazione variabili
date = input('Inserisci data in formato DD-MM-YYYY: ')
day, month, year = map(int, date.split('-'))
datam = datetime.date(year, month, day)
causale = int(input("Inserire 1 per Entrata e 2 per Uscita :"))
descr = input("Descrizione movimento: ")
importo = float(input("Importo: "))
Ne approfitto per farVi un altra domanda.

Vorrei che all'avvio del script in questo caso (futuro programmino quando avrò acquisito le conoscenze) si vada a leggere un dato, in questo caso il saldo nell'ultima riga della tabella e memorizzi tale dato in una variabile.




Non ho trovato nessuna informazione ne sul libro che sto leggendo ( Pensare in Python di Allen Downey) ne online.




Il codice che ho utilizzato è:




import pymysql.cursors
import datetime

print('Benvenuto nel programma Cassa')
# Connessione
connection = pymysql.connect(host='localhost',
                             user='root',
                             password='123',
                             db='cassa',
                             charset='utf8mb4',
                             cursorclass=pymysql.cursors.DictCursor)

#Andiamo a leggere l'ultimo valore della tavbella movimenti colonna Saldo

try:
    cursor = connection.cursor() 
    sql_saldo = "SELECT Saldo From movimenti"
    cursor.execute(sql_saldo)
    _saldo = cursor.fetchone()
    if _saldo == None:
        saldo = 0
    else :
        saldo = _saldo
    print('Il saldo attuale è: ',saldo)
except:
    print ('Errore!!!!)    

# Inserimento dati e memorizzazione variabili
date = input('Inserisci data in formato DD-MM-YYYY: ')
day, month, year = map(int, date.split('-'))
datam = datetime.date(year, month, day)
causale = int(input("Inserire 1 per Entrata e 2 per Uscita :"))
descr = input("Descrizione movimento: ")
importo = float(input("Importo: "))
saldof = float(saldo)
# Scrittura database
try:
    with connection.cursor() as cursor:
        sql = "INSERT INTO movimenti (DataMovimento, ID Causale, Descrizione, Importo, Saldo) VALUES( %s, %s, %s, %s, %s)"
        if causale == 1:
           saldo = saldof + importo
        elif causale == 2:
           saldo = saldof - importo
           
        cursor.execute(sql, (datam, causale, descr, importo, saldof))
        connection.commit()

    with connection.cursor() as cursor:
        sql1 = "SELECT DataMovimento, ID Causale, Descrizione, Importo, Saldo FROM movimenti"
        cursor.execute(sql1)
        for riga in cursor.fetchall():
            print(riga)
finally:
    connection.close()


L'errore è:





Benvenuto nel programma Cassa
Il saldo attuale è:  {'Saldo': 350.5}
Inserisci data in formato DD-MM-YYYY: 02-10-2018
Inserire 1 per Entrata e 2 per Uscita :1
Descrizione movimento: Incasso
Importo: 235
Traceback (most recent call last):
  File "C:\Users\Utente\Desktop\Bozza Programma.py", line 35, in <module>
    saldof = float(saldo)
TypeError: float() argument must be a string or a number, not 'dict'
>>> 
che da quello che ho capito è proprio il type della variabile che ho letto dal database.




Spero di non essere andato off topic.




Saluti



--- Ultima modifica di Kestrel in data 2018-10-03 12:01:40 ---
Benvenuto nel programma Cassa
Il saldo attuale è:  {'Saldo': 350.5}
Inserisci data in formato DD-MM-YYYY: 02-10-2018
Inserire 1 per Entrata e 2 per Uscita :1
Descrizione movimento: Incasso
Importo: 235
Traceback (most recent call last):
  File "C:\Users\Utente\Desktop\Bozza Programma.py", line 35, in <module>
    saldof = float(saldo)
TypeError: float() argument must be a string or a number, not 'dict'
>>> 
che da quello che ho capito è proprio il type della variabile che ho letto dal database.
Al volo vedo che stai provando a convertire un dizionario, cioè {'Saldo': 350.5}, in un float ed ovviamente ottieni un errore.

Ricontrolla questo passaggio.

Cya

Sì, come dice daniele. Per qualche ragione pymysql ti restituisce il risultato della query come un dizionario invece che come una più normale tupla di valori (devi vedere la documentazione per scoprire come mai, e come eventualmente cambiare questa cosa se non ti va). Chiaramente fare "float" di un dizionario dà errore; se vuoi tenerti il dizionario, devi fare "float" del _valore_ del dizionario per la chiave "Saldo".


Detto questo, non so come sia strutturata la tua tabella, ma a occhio la query è sbagliata. Se fai fetchone() su un cursore, quello che ottieni è la *prima* riga della tua query, non l'ultima.

Vi ringrazio per le dritte che mi avete dato ma non ho trovato nessuna risposta sia per quanto riguarda il recupero di valori dal database come tupla e non come dizionario e sia sulla funzione cursors per intercettare l'ultima riga del dabase





Il pacchetto PyMySql dovrebbe contenere la libreria pura MySql basata sul PEP 249. In quest'ultima non ho trovato risposta



Avete suggerimenti su dove e con quali criteri effettuare la ricerca per avere maggiori informazioni?

Grazie






Pagina: 1 2 Avanti



Esegui il login per scrivere una risposta.