sqlalchemy - 多个文件 - 关系

时间:2012-01-07 03:58:11

标签: python sqlalchemy

我的两个单独的文件,客户和地址。地址将用于其他地方,例如供应商具有地址。客户类需要以三种方式引用地址类。客户有一个默认的发货地址(一对一)是一个默认的地址(一对一)和一个多个地址的列表,如果不需要默认值,可以选择这些地址。 ar.py文件中的customer类和地址类位于global.py文件中。

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

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

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文件中类地址的相同类型布局在供应商文件中。

再次感谢您的帮助! 保罗

1 个答案:

答案 0 :(得分:2)

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

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

SQLAlchemy将处理将这些转换为对象。

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

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

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