Visualizza post

Questa sezione ti permette di visualizzare tutti i post inviati da questo utente. N.B: puoi vedere solo i post relativi alle aree dove hai l'accesso.


Post - ery

Pagine: [1]
1
Ciao a tutti,
da qualche settimana ho cominciato a studiare Python e mi stavo approcciando alla creazione di microservizi.
Facendo un po' di ricerche in rete sono ho capito che le librerie da usare sostanzialmente sono due:

  • Flask-RESTX per la creazione degli end point del servizio
  • SQLAlchemy per l'accesso al DB

Leggendo dalle pagine ufficiali delle rispettive librerie, stavo provando a creare una semplice applicazione che facesse le 4 operazioni base sul DB

  • INSERT
  • UPDATE
  • DELETE
  • SELECT

Quello che ho fatto, a partire dagli esempi sulle pagine ufficiali quindi, è stato creare un modulo con 4 end poi per le 4 operazioni,
un modulo per la connessione al db e un modulo di accesso al db che eseguisse le query in questione (ho usato l'approccio classico transazionale non ORM)

Il problema che sto riscontrando è nelle insert e nelle delete, qualunque sia la metodologia con cui le eseguo:

  • Se le faccio usando la connessione, l'operazione va in rollback
  • Se le faccio usando la sessione ricevo l'errore
    • (sqlite3.OperationalError) cannot commit transaction - SQL statements in progress

La cosa strana è che quando stavo studiando SQLAlchemy avevo creato sempre un file di connessione ed uno di accesso ad i dati e tutto funzionava.
Ora invece, passando per la chiamata al servizio, pare che non vada.
Sono sicuro che mi sto perdendo qualcosa legata alla conoscenza ancora iniziale di Python e quindi a qualche errore negli oggetti o roba del genere, quindi spero che qualcuno qui mi dica che errore sto commettendo.

Di seguito vi riporto il codice.
Immagino che sia pieno di errori, perdonatemi, mi farebbe piacere se mi indicaste quali e come va scritto meglio il codice.

Un altra cosa, lo so che Flask ha al suo interno un implementazione di SQLAlchemy, ma ho preferito utilizzare la libreria standard,
anche perché su internet qualcuno sconsiglia di utilizzare quella implementazione e poi perché penso che se si comincia da zero,
meglio partire della librerie base che da qualche implementazione modificata.


Il database è costituito da una semplice tabella Nominativo, nel codice potete leggere il dettaglio sulla tabella

File "applicazione.py"

from flask import Flask
from flask_restx import Api, Resource, fields
from DAO import NominativoDAO

app = Flask(__name__)
app.wsgi_app = ProxyFix(app.wsgi_app)
api = Api(app, version='1.0', title='Nominativi',
    description='Esempio di microservizi in python',
)

ns = api.namespace('Nominativi', description='Elenco persone ed eta''')

nominativo = api.model('Nominativo', {
    'id': fields.Integer(readonly=True, description='Identificativo del nome'),
    'nome': fields.String(required=True, description='nome della persona'),
    'cognome': fields.String(required=True, description='cognome della persona'),
    'eta': fields.Integer(required=True, description='eta'' della persona')
})


@ns.route('/')
class NominativoList(Resource):
    '''Mostra la lista di tutti i nominativi'''
    @ns.doc('list_nominativi')
    @ns.marshal_list_with(nominativo)
    def get(self):
        '''Elenca tutti i nominativi'''
        nom = NominativoDAO();
        result = nom.getList()
        return result

    @ns.doc('create_nominativo')
    @ns.expect(nominativo)
    @ns.marshal_with(nominativo, code=201)
    def post(self):
        '''Crea un nominativo'''
        nom = NominativoDAO();
        result = nom.create(api.payload)
        return result, 201


@ns.route('/<int:id>')
@ns.response(404, 'Nominativo non trovato')
@ns.param('id', 'Identificatore del nominativo')
class Nominativo(Resource):
    '''Mostra un singolo nominativo'''
    @ns.doc('get_nominativo')
    @ns.marshal_with(nominativo)
    def get(self, id):
        '''Recupera il nominativo corrispondente'''       
        nom = NominativoDAO();
        return nom.get(id)

    @ns.doc('delete_nominativo')
    @ns.response(204, 'Nominativo cancellato')
    def delete(self, id):
        '''Cancella un nominativo tramite il suo id'''       
        nom = NominativoDAO();
        nom.delete(id)
        return '', 204

    @ns.expect(nominativo)
    @ns.marshal_with(nominativo)
    def put(self, id):
        '''Aggiorna il nominativo'''   
        nom = NominativoDAO();
        nom.update(id, api.payload)
        return api.payload


if __name__ == '__main__':
    app.run(debug=True)


File Connection.py

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

SQLALCHEMY_DATABASE_URL = "sqlite:///./nominativi.sqlite"

engine = create_engine(SQLALCHEMY_DATABASE_URL, echo=True, future=True)

Session = sessionmaker(bind=engine, autocommit=False, autoflush=False)


File DAO.py

from Connection import engine, Session
from sqlalchemy import text

class Nominativo(object):
    def __init__(self):
        self.id = 0
        self.nome=""
        self.cognome=""
        self.eta=0
   

class NominativoDAO(object):
    def __init__(self):
        self.counter = 0
        self.nominativi = []
       
    def getList(self):
        with engine.connect() as conn:
            result = conn.execute(text("SELECT * FROM Nominativi"))
            for row in result:
                nominativo = Nominativo()
                nominativo.id = row.id 
                nominativo.nome = row.nome 
                nominativo.cognome = row.cognome
                nominativo.eta = row.eta
                self.nominativi.append(nominativo)
        return self.nominativi

    def get(self, id):
        with engine.connect() as conn:
            result = conn.execute(text("SELECT * FROM Nominativi where id=:id"), [{"id": id}])
            for row in result:
                nominativo = Nominativo()
                nominativo.id = row.id 
                nominativo.nome = row.nome 
                nominativo.cognome = row.cognome
                nominativo.eta = row.eta
                self.nominativi.append(nominativo)
        return self.nominativi
        #api.abort(404, "Nominativo {} non trovato".format(id))

    def create(self, data):     
        session = Session() 
        try:
            result = session.execute(
                text("INSERT INTO Nominativi (nome, cognome, eta) VALUES (:n, :c, :e) RETURNING id"),
                    [{"n": data['nome'], "c": data['cognome'], "e": data['eta']}]
                )           
            session.commit()
            session.close()
        except Exception as e: print(e)
        data['id'] = result.lastrowid
        return data

    def update(self, id, data):
        try:
            with engine.connect() as conn:
                conn.execute(text("UPDATE Nominativi SET nome=:n, cognome=:c, eta=:e where id=:id"),
                            [
                                {"n": data['nome'], "c": data['cognome'], "e": data['eta'], "id": id}
                            ]
                        )           
                conn.commit()       
        except Exception as e: print("Error:", e)
        return data

    def delete(self, id):
        try:
            with engine.connect() as conn:
                conn.execute(text("Delete FROM Nominativi where id=:id"), [{"id": id}])
            conn.commit()
        except Exception as e: print(e)
        return self.nominativi

2
Benvenuto e regolamento / Salve
« il: Ottobre 11, 2021, 10:46 »
Ciao,
sto cominciando a studiare python e spero di poter  trovare suporto qui da voi per i mie dubbi.

Grazie :)

Pagine: [1]