Operazioni di scrittura

Creare un nuovo record

La Tabella implementa un metodo insert che riceve in modo polimorfico o un dizionario o una bag contenente i dati del nuovo record.

nuovo_prodotto = dict(codice='TTFFG', descrizione='Prodotto Nuovo')
tbl_prodotto.insert(nuovo_prodotto)
mydb.commit()

È quindi possibile passare al metodo insert un dizionario con chiavi le colonne della tabella, e valori i valori del record che stiamo inserendo.

Suggerimento

Se guardiamo il record dopo il nuovo inserimento, noteremo che non sono state popolate solo le colonne da noi inserite, ma anche una serie di Colonne di sistema , ovviamente se presenti nella configurazione della Tabella.

Si noti che è possibile passare nella insert anche la primary key, in quel caso verrà effettuato un check in merito all’esistenza o meno della primary key nel database. Se invece si utilizza l” id di sistema di Genropy e questo viene omesso, sarà l’ORM a invocare in autonomia il metodo pkeyValue per generare una nuova primary key:

print (nuovo_prodotto)

{'codice': 'TTFFG', 'descrizione': 'Prodotto Nuovo', 'id': 'KCdaL3JIMful1fXF4mB11A', '__ins_ts': datetime.datetime(2020, 6, 10, 10, 22, 26, 483704), '__mod_ts': datetime.datetime(2020, 6, 10, 10, 22, 26, 483737), '__ins_user': None}

Suggerimento

Utilizzando il metodo raw_insert al posto del semplice insert sarà possibile eseguire l’operazione di creazione del record senza innescare i Trigger della tabella su cui si sta operando

Una procedura alternativa: la newrecord

Genropy mette a disposizione una procedura alternativa alla procedura standard di inserimento di un dizionario, il metodo newrecord:

nuova_fattura = self.db.table('fatt.fattura').newrecord(data=self.db.workdate, cliente_id=cliente)
self.db.table('fatt.fattura').insert(new_contact)
self.db.commit()

Anche in questo caso il metodo newrecord crea un record nella tabella individuata, popolando automaticamente i sysFields.

commit e deferToCommit

Al termine di una qualsiasi procedura di inserimento o di modifica di uno o più record è necessario procedere con il commit sul database, ovvero il momento in cui la transazione viene effettivamente eseguita e il record viene reso disponibile a tutti dopo la modifica sul database. In caso contrario la modifica rimarrà invece sul client e non sarà mai trasferita al database.

self.db.commit()

In caso di inserimenti o modifiche multiple, ad esempio l’aggiunta o la rimozione simultanea di molte righe di un documento di tipo testata/righe (un ordine, una fattura, un documento di trasporto), può essere utile posticipare un evento al momento del commit, al fine di ridurre il numero di scritture al minimo indispensabile.

Suggerimento

Questo è particolarmente evidente in presenza di Trigger che intervengono all’inserimento o alla modifica di un record: se per esempio viene usato un trigger_onInserted per effettuare un (ri)calcolo dei totali dell’ordine, questo processo verrebbe ripetuto a ogni inserimento di nuova riga.

Genropy mette a disposizione il metodo deferToCommit, che permette di rinviare la chiamata a un altro metodo sino al momento del commit. Ad esempio in Sandbox, nel model di fattura_riga troviamo:

def aggiornaFattura(self,record):
      fattura_id = record['fattura_id']
      self.db.deferToCommit(self.db.table('fatt.fattura').ricalcolaTotali,
                                  fattura_id=fattura_id,
                                  _deferredId=fattura_id)

La chiamata a ricalcolaTotali (effettuata tramite i trigger a ogni inserimento, modifica o eliminazione di una riga) viene così posticipata al momento del commit, evitando di ripetere l’operazione a ogni singola modifica. Si noti che il metodo deferToCommit riceve:

  • il metodo la cui chiamata si vuole posticipare (in questo caso ricalcolaTotali)
  • i parametri richiesti dal metodo (in questo caso fattura_id)
  • un altro parametro facoltativo _deferredId, che indica la pkey della testata, al variare della quale verrà comunque eseguito il metodo da posticipare (in questo caso, il ricalcolo non verrà effettuato al commit di tutte le operazioni, ma al termine delle operazioni relative alle righe della stessa fattura)

Autore della sezione: Davide Paci