Dividir o módulo ORM sem criar importações cíclicas ou efeitos colaterais

5

Prefácio

Eu tenho uma biblioteca ORM para um banco de dados relacional de imóveis. A estrutura usada é peewee . A biblioteca contém ~ 60 modelos, cada um representando uma tabela distinta. Os modelos representam uma estrutura de dados imobiliários (pré-definida, proprietária) baseada em XML. Há uma tabela de nível superior chamada immobilie (imobiliária), que representa a raiz do documento XML.

Cada modelo definiu os métodos de classe from_dom(cls, dom) e from_dict(cls, dictionary) e os métodos to_dom(self) e to_dict(self) , que contêm uma quantidade considerável de código.

Problema

A biblioteca funciona bem, mas atualmente o módulo possui 10255 linhas de código, o que dificulta muito a leitura e a manutenção.

Primeira ideia

Minha ideia, portanto, era dividir o módulo em vários módulos menores, cada um para um modelo. Isso, no entanto, cria os seguintes problemas:

1) peewee requer a configuração do modelo da respectiva chave estrangeira na respectiva definição de modelo. Por simplicidade de apresentação, vamos supor:

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)

Assim, o modelo referenciado deve ser importado na respectiva definição de modelo.

2) Como o exemplo com a propriedade semi_orphans deve esclarecer, quase todos os modelos referenciados também precisam conhecer seus modelos de referência para certos métodos de seleção.

Isso criaria importações cíclicas não resolvidas, como já testei com partes do código.

Segunda ideia

Assim, pensei, eu poderia terceirizar os métodos de backreferencing em próprias subclasses em moules separados. No entanto, isso os tornaria indisponíveis ao fazer algo como:

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

Isso dispararia um AttributeError , pois some_child.mom retornaria o modelo base sem o método semi_orphans .

Pergunta

Eu estou negligenciando alguma coisa? É realmente impossível dividir a biblioteca em componentes menores para aumentar a qualidade e a capacidade de manutenção do código, porque não há como se livrar das dependências cíclicas?

    
por Richard Neumann 09.04.2018 / 15:58
fonte

1 resposta

0

Depois de mais algumas considerações, comecei a dividir os modelos nos modelos ORM reais e terceirizei a serialização JSON e XML DOM (de-) em um pacote próprio, cada um, usando classes mixin. Eu também resolvi o problema antecipado das chaves estrangeiras não retornando o composit, mas os modelos básicos. peewee tem uma classe DeferredForeignKey que desconhecia. Usá-lo para definir os modelos compostos (com mixins) mais tarde, deve resolver esse problema.

    
por 31.08.2018 / 10:42
fonte