regeint
regeint

Reputation: 888

Composite foreign key reference in python ORM storm

Here is my model:

class ProductCategory(Storm):
    __storm_table__ = 'product_category'

    pcat_no = Int(primary = True)
    pcat_name = Unicode()

    pitem = ReferenceSet(pcat_no, 'ProductItem.pcat_id')
    catpurchase = ReferenceSet(pcat_no, 'Purchase.pcategory_id')

class ProductItem(Storm):
    __storm_table__ = 'product_item'
    __storm_primary__ = 'pcat_id', 'pitem_no'

    pcat_id = Int()
    pitem_no = Int()
    pitem_name = Unicode()

    pcat = Reference(pcat_id, ProductCategory.pcat_no)
    purchase = ReferenceSet([pcat_id, pitem_no], [Purchase.pcategory_id, Purchase.pitem_id])

class Purchase(Storm):
    __storm_table__ = 'purchase'

    id = Int(primary = True)
    date = Date()
    pcategory_id = Int() # it must refer to pcat_no of ProductCategory & pcat_id of ProductItem
    pitem_id = Int() # It must refer to pitem_no of ProductItem

    pcategory = Reference(pcategory_id, ProductCategory.pcat_no)
    product = Reference([pcategory_id, pitem_id], [ProductItem.pcat_id, ProductItem.pitem_no])

The condition is that I want to select either only category OR both category & item available from the tables(with drop-down on each). And would like to have references back to category details OR both category & item details with referenceset. I want to list the purchase record with category_no & name (if only pcategory_id is supplied) OR category_no & name, item_no & name if both the category & item is supplied. & insert the record that satisfies as per my requirement. The major problem that I am having is when I list the record with:

print purchase_record.pcategory.pcat_name #it works fine but,
print purchase_record.product.pitem_name # it gives the error "RuntimeError: Reference used in an unknown class"
#thought 'purchase_record.pitem_id' holds some value

I am using flask, & storm as ORM. Is there any way I can get the product category name & product item name with proper references among the tables?

Upvotes: 1

Views: 447

Answers (1)

James Henstridge
James Henstridge

Reputation: 43949

The problem here is that you are using lists to declare your composite keys. If you use tuples instead, then your example should work as expected:

class Purchase(Storm):
    ...
    product = Reference((pcategory_id, pitem_id), (ProductItem.pcat_id, ProductItem.pitem_no))

While the error message is a bit opaque, there are reasons for not using lists here: the two ends of the reference should not change, so a mutable type like a list is not really appropriate.

Upvotes: 0

Related Questions