实际上我正在使用python 3.4设计一个大型桌面应用程序。 我选择了端口和适配器架构,就像六边形架构一样。 它的主要目的是使用可重用的组件。
要组织代码并制定一些规则,我们将使用Zope组件架构(ZCA)
所以要做一些POC,我正在创建数据库组件。 但是使用ORM的事实阻止了我。我的意思是我设计了一些看起来像的数据库组件:
-IDatabase -IDatabaseConfig -IEntity -IKey -IReader -IWriter ... 和实施。
SQLAlchemy管理很多东西,我不知道如何使我的组件可重用。
我找到了这段代码:
#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')
但我认为这段代码很难与SQLAlchemy结合使用。 那么我应该对我的架构使用什么方法呢?
由于实体必须是应用程序的中心(域层),如果我需要更改我的数据库组件而不使用SQLAlchemy,那么该解决方案会出现问题?
我对所有建议持开放态度。
答案 0 :(得分:0)
我使用ORM作为实体对象并将Adapters放在它上面:
在interfaces.py
中的某个地方定义了API:
from zope.interface import Interface
class IEntity(Interface):
def pi_ing():
'''makes the entity go "pi-ing" '''
定义了数据库模型:
class EntityA(Base):
# .. table and relationship definitions are here
实施API的其他地方:
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)
现在一切都已到位。代码的业务逻辑中的某个地方 当你获得entity_a的id时,你可以这样做:
from interfaces import IEntityAProtocol
def stuff_which_goes_splat():
# ...
entity_id = got_from_somewhere()
IEntityProtocol(entity_id).pi_ing()
现在,您可以完全独立地实现接口,数据库实体和API逻辑。好的方面是,你不必只调整像对象的int ID这样的原始东西,你可以适应任何东西,只要你能实现从你的适配器到数据库实体的直接转换。
警告:当然,相对于执行时间点,getGlobalSiteManager().registerAdapter(get_entity_a_by_id)
必须已经被调用。