2015-10-23 2 views
2

En fait, je suis en train de concevoir une grande application pour desktop avec python 3.4. J'ai choisi l'architecture du port et de l'adaptateur, connue sous le nom d'architecture hexagonale. Le but principal de travailler avec des composants réutilisables.Créer un composant réutilisable avec ZCA et SQLAlchemy

Pour organiser le code et mettre des règles que nous utiliserons l'Zope Component Architecture (ZCA)

Donc, pour faire des POC, je crée le composant de base de données. Mais le fait de travailler avec un ORM me bloque. Je veux dire que je y construisirent composant base de données qui ressemblait à:

-IDatabase -IDatabaseConfig -IEntity -IKey -IReader -IWriter ... et la mise en œuvre.

SQLAlchemy beaucoup de choses et je ne sais pas comment rendre mon composant réutilisable.

j'ai trouvé ce code:

#Reflect each database table we need to use, using metadata 
class Customer(Base): 
    __table__ = Table('Customers', metadata, autoload=True) 
    orders = relationship("Order", backref="customer") 

class Shipper(Base): 
    __table__ = Table('Shippers', metadata, autoload=True) 
    orders = relationship("Order", backref="shipper") 

class Product(Base): 
    __table__ = Table('Products', metadata, autoload=True) 
    supplier = relationship('Supplier', backref='products') 
    category = relationship('Category', backref='products') 

Mais ce code est couplé à peine avec realy SQLAlchemy je suppose. Alors, quelle est l'approche que je devrais utiliser avec mon architecture?

Étant donné que les entités doivent être le centre de l'application (couche de domaine), cela posera un problème avec cette solution si je dois modifier mon composant de base de données et ne pas utiliser SQLAlchemy?

Je suis ouvert à toutes les suggestions.

Répondre

0

J'utilise le ORM comme des objets d'entité et de mettre adaptateurs dessus:

quelque part dans un interfaces.py l'API est définie:

from zope.interface import Interface 

class IEntity(Interface): 

    def pi_ing(): 
     '''makes the entity go "pi-ing" ''' 

quelque part le modèle de base de données est définie:

class EntityA(Base):  
    # .. table and relationship definitions are here 

ailleurs, l'API est implémentée:

from zope.interface import implementer 
from zope.component import adapter, getGlobalSiteManager 

class EntityAPI(object): 

    def __init__(self, instance): 
     self.instance = instance 

    def pi_ing(self): 
     # make "pi_ing" 


@implementer(IEntityAProtocol) 
@adapter(int) 
def get_entity_a_by_id(id): 
    return EntityAPI(session().query(EntityA).get(id)) 

getGlobalSiteManager().registerAdapter(get_entity_a_by_id) 

Maintenant tout est en place. Quelque part dans la logique métier du code lorsque vous obtenez l'identifiant d'un entity_a vous pouvez simplement faire:

from interfaces import IEntityAProtocol 

def stuff_which_goes_splat():   
    # ... 
    entity_id = got_from_somewhere() 
    IEntityProtocol(entity_id).pi_ing() 

Maintenant vous avez une mise en œuvre complète de l'interface séparée, entité de base de données et la logique de l'API. La bonne chose est, vous n'avez pas besoin d'adapter seulement des choses aussi primitives comme un ID d'objet d'un objet, vous pouvez adapter n'importe quoi, tant que vous pouvez implémenter une transformation directe de votre adapttee à l'entité de base de données. Remarque: par rapport au moment de l'exécution, le getGlobalSiteManager().registerAdapter(get_entity_a_by_id) doit déjà avoir été appelé.