sqlalchemy /表设置

时间:2012-01-13 01:38:33

标签: python database-design sqlalchemy

我有物品,仓库和物品都在仓库里。

所以我的表中包含有关项目(sku,描述,成本......)的信息以及描述仓库(位置,代码,名称......)的表格。现在我需要一种存储库存的方法,以便我知道仓库Y中有X个物品。物品可以存放在任何仓库中。

我如何设置它们之间的关系并存储数量?

class Item(DeclarativeBase):
    __tablename__ = 'items'
    item_id = Column(Integer, primary_key=True,autoincrement=True)
    item_code = Column(Unicode(35),unique=True)
    item_description = Column(Unicode(100))
    item_long_description = Column(Unicode())
    item_cost = Column(Numeric(precision=13,scale=4))
    item_list = Column(Numeric(precision=13,scale=2))
    def __init__(self,code,description,cost,list):
        self.item_code = code
        self.item_description = description
        self.item_cost = cost
        self.item_list = list

class Warehouse(DeclarativeBase):
    __tablename__ = 'warehouses'
    warehouse_id = Column(Integer, primary_key=True, autoincrement=True)
    warehouse_code = Column(Unicode(15),unique=True)
    warehouse_description = Column(Unicode(55))

如果我是正确的,我会使用类似......的中间表设置多对多。

item_warehouse = Table(
    'item_warehouse', Base.metadata,
    Column('item_id', Integer, ForeignKey('items.item_id')),
    Column('warehouse_id', Integar, ForeignKey('warehouses.warehouse_id'))
)

但是我需要在这张桌子上启动数量,但由于它不是自己的类,我不确定这是怎么回事。

对此进行建模并在我的应用中使用它的“最佳”做法是什么?

2 个答案:

答案 0 :(得分:2)

您必须使用"Association Object"

我试着给你提示你必须创建的问题,就像你在问题中提到的那样

item_warehouse = Table( 'item_warehouse', 
                        Base.metadata, 
                        Column('item_id', 
                               Integer, 
                               ForeignKey('items.item_id')
                        ), 
                        Column('warehouse_id', 
                               Integar, 
                               ForeignKey('warehouses.warehouse_id')
                        ), 
                        Column('qty',
                               Integer,
                               default=0,
                        ),
                      )

现在您可以在单个对象中添加warehouseitemqty,并且您必须编写将warehouse_iditem_id的方法并获取sum qty代表那些主题。

希望这可以帮助您解决问题。

答案 1 :(得分:2)

型号:

如@Lafada所述,您需要一个关联对象。因此,我将创建一个SA持久对象,而不仅仅是一个表:

class ItemWarehouse(Base):
    # version-1:
    __tablename__ = 'item_warehouse'
    __table_args__ = (PrimaryKeyConstraint('item_id', 'warehouse_id', name='ItemWarehouse_PK'),)
    # version-2:
    #__table_args__ = (UniqueConstraint('item_id', 'warehouse_id', name='ItemWarehouse_PK'),)
    #id = Column(Integer, primary_key=True, autoincrement=True)

    # other columns
    item_id = Column(Integer, ForeignKey('items.id'), nullable=False)
    warehouse_id = Column(Integer, ForeignKey('warehouses.id'), nullable=False)
    quantity = Column(Integer, default=0)

这涵盖了模型要求,包括以下内容:

  • 添加了一个PrimaryKey
  • 添加了涵盖(item_id, warehouse_id)对的UniqueConstraint。

在上面的代码中,这有两种解决方法:

  • version-1:使用复合主键(必须是唯一的)
  • version-2:使用简单的主键,但也添加了显式的唯一约束[我个人更喜欢这个选项]

关系:关联对象

现在。您可以按原样使用关联对象,它看起来类似于:

w = Warehouse(...)
i = Item(name="kindle", price=...)
iw = ItemWarehouse(quantity=50)
iw.item = i
w.items.append(i)

关系:Association Proxy扩展名

或者,您可以更进一步使用Composite Association Proxies示例,您可以配置类似于此的关联对象的字典式访问:

w = Warehouse(...)
i = Item(name="kindle", price=...)
w[i] = 50 # sets the quantity to 50 of item _i_ in warehouse _w_
i[w] = 50 # same as above, if you configure it symmetrically

注意:关系定义的代码看起来可能不易读取,但使用模式非常好。因此,如果这个选项太多无法消化,我会从Association Object开始,可能还有一些辅助函数来添加/获取/更新项目库存,最终转移到Association Proxy extesion。