Modulo ORM diviso senza creare importazioni cicliche o effetti collaterali

5

Prefazione

Ho una libreria ORM per un database relazionale immobiliare. Il framework utilizzato è peewee . La libreria contiene ~ 60 modelli, ognuno dei quali rappresenta una tabella distinta. I modelli rappresentano una (pre-definita, proprietaria) struttura dei dati immobiliari basata su XML. C'è una tabella di livello superiore chiamata immobilie (proprietà immobiliare), che rappresenta la radice del documento XML.

Ogni modello ha definito i metodi di classe from_dom(cls, dom) e from_dict(cls, dictionary) e metodi to_dom(self) e to_dict(self) che contengono una notevole quantità di codice.

Problema

La libreria funziona bene così com'è, ma il modulo ha attualmente 10255 linee di codice, il che rende piuttosto difficile la lettura e la manutenzione.

Prima idea

La mia idea era quindi quella di dividere il modulo in diversi moduli più piccoli, ciascuno per un modello. Questo, tuttavia, crea i seguenti problemi:

1) peewee richiede l'impostazione del rispettivo modello di chiave esterna nella rispettiva definizione del modello. Per semplicità di presentazione assumiamo:

class Parent(Model):

    @property
    def semi_orphans(self):
         return Child.select().where(
             (Child.mom == self & Child.dad >> None)
             | (Child.mom >> None & Child.dad == self))


class Child(model):
    mom = ForeignKeyField(Parent)
    dad = ForeignKeyField(Parent)

Quindi il modello di riferimento deve essere importato nella rispettiva definizione del modello.

2) Come dovrebbe chiarire l'esempio con la proprietà semi_orphans , quasi tutti i modelli di riferimento devono conoscere i loro modelli di riferimento per determinati metodi di selezione.

Ciò creerebbe importazioni cicliche irrisolvibili come ho già provato con parti del codice.

Seconda idea

Così ho pensato, potevo esternalizzare i metodi di backreferencing in sottoclassi in mule separate. Ciò tuttavia li renderebbe non disponibili quando si fa qualcosa del tipo:

some_child = Child.get()
semi_orphans = some_child.mom.semi_orphans

Ciò attiverebbe un AttributeError poiché some_child.mom restituirebbe il modello base senza il metodo semi_orphans .

Domanda

Sto trascurando qualcosa? È davvero impossibile suddividere la libreria in componenti più piccoli per aumentare la qualità e la manutenibilità del codice perché non c'è modo di eliminare le dipendenze cicliche?

    
posta Richard Neumann 09.04.2018 - 15:58
fonte

1 risposta

0

Dopo qualche considerazione in più ho iniziato a suddividere i modelli nei modelli ORM attuali e ho esternalizzato la serializzazione de-JSON e JSON su un proprio pacchetto, ciascuno, usando classi di mixin. Ho anche risolto il problema previsto delle chiavi esterne che non restituiscono il composito, ma i modelli di base. peewee ha una classe DeferredForeignKey di cui non ero a conoscenza. Usarlo per impostare i modelli composit (con i mixin) in un secondo momento, dovrebbe risolvere questo problema.

    
risposta data 31.08.2018 - 10:42
fonte

Leggi altre domande sui tag