2012-01-07 86 views
1

我有两个单独的文件,客户和地址我的两个类。地址将在其他地方使用,例如供应商具有地址。客户类需要通过三种方式引用地址类。客户有一个默认发货地址(一对一)缺省帐单地址(一对一)和他的多个地址列表,如果不需要默认值,可以选择。 ar.py文件和地址类中的客户类位于global.py文件中。sqlalchemy - 多个文件 - 关系

一对一的工作,但一对多列表我无法弄清楚如何使它与两个不同的文件中的类一起工作。无循环问题。

感谢您能提供任何见解......

globals.py 
from erp.model import DeclarativeBase, metadata, DBSession 

class Address(DeclarativeBase): 
    __tablename__ = 'addresses' 
    address_id = Column(Integer,primary_key=True) 
    name = Column(Unicode(100)) 
    address_one = Column(Unicode(100)) 
    address_two = Column(Unicode(100)) 
    address_three = Column(Unicode(100)) 
    city = Column(Unicode(100)) 
    state = Column(Unicode(100)) 
    zip_code = Column(Unicode(100)) 
    phone = Column(Unicode(100)) 
    fax = Column(Unicode(100)) 
    contact = Column(Unicode(100)) 

ar.py ... 
from erp.model.globals import Address 

class Customer(DeclarativeBase): 
    __tablename__ = 'customers' 
    customer_id = Column(Integer, primary_key=True) 
    customer_name = Column(Unicode(100)) 
    discount = Column(Float) 
    #bill_to_id = Column(Integer, ForeignKey('addresses.address_id')) 
    #bill_to = relation(Address,primaryjoin=bill_to_id==Address.address_id,uselist=False) 
    ship_to_id = Column(Integer, ForeignKey('addresses.address_id')) 
    ship_to = relation(Address,primaryjoin=ship_to_id==Address.address_id,uselist=False) 
    locations = relation(Address,backref="customer",primaryjoin='customers.customer_id'=='addresses.customer_id') 

我可以使这项工作就好了,如果我在一个文件中所拥有的一切然而,这与上一个有一堆东西的项目布局复杂文件或者更糟糕的是在ar文件和供应商文件中复制相同种类的地址布局。

再次感谢您的帮助! Paul

回答

2

您可以使用字符串而不是实例创建模型。例如,

ship_to = relation('Address', ...) 

SQLAlchemy将处理将它们转换为对象。

一对多通常通过指向客户的地址上的fkey进行处理。但是,如果您将这些地址用于多种用途,这种方式将无法正常工作。如果你希望数据库中的所有地址都存储在一个表中,那么我建议在每个表和地址之间添加链接表。例如,customer_addresses将有地址和客户的密码。另一种选择是为customer_addresses和vendor_addresses创建一个单独的表。如果你想这样做最好的办法是创建一个AddressMixin,你可以应用于不同的对象:

class AddressMixin(object): 
    @declared_attr 
    def street(cls): 
     return Column(Text, ...) 

class CustomerAddress(Base, AddressMixin): 
    __tablename__ = 'customer_addresses' 
    id = ... 
+0

太棒了。然而,这很有效(除非我错了),我仍然需要在地址类上声明一对多。因此,这个类将开始具有customer_id .. customer = relation ...,然后再有两个供应商的条目,等等,以便需要使用这个类。更糟糕的是,随着应用程序的增长,我希望使用这样的地址,我必须修改地址。有没有办法在客户课上做到这一切? – Ominus 2012-01-07 04:10:21

+0

看看关系的'backref'参数,你可以在任何一个类上定义关系,它将通过backref应用到另一端。 – 2012-01-07 04:13:11

+0

我明白了。为了保持代码清洁,我会更好地拥有一个继承地址的customer_address类,并且只添加customer_id foreighnkey字段?这是我猜想的一个害虫实践问题。 – Ominus 2012-01-07 04:14:40