When you are iterating over a table, or performing a multi-get
operation, by default only rows are retrieved from the table on
which you are operating. However, you can use
MultiRowOptions
to specify that parent and child tables are to be retrieved as
well.
When you do this, parent tables are retrieved first, then the table you are operating on, then child tables. In other words, the tables' hierarchical order is observed.
The parent and child tables retrieved are identified using a
list of table names, which is then provided to the
MultiRowOpetions
object's ONDB_INCLUDED_TABLES
property.
When operating on rows retrieved from multiple tables, it is your responsibility to determine which table the row belongs to.
For example, suppose you create a table with a child and grandchild table like this:
CREATE TABLE prodTable ( prodType STRING, typeDescription STRING, PRIMARY KEY (prodType) )
CREATE TABLE prodTable.prodCategory ( categoryName STRING, categoryDescription STRING, PRIMARY KEY (categoryName) )
CREATE TABLE prodTable.prodCategory.item ( itemSKU STRING, itemDescription STRING, itemPrice FLOAT, vendorUID STRING, inventoryCount INTEGER, PRIMARY KEY (itemSKU) )
With tables containing data like this:
Row 1:
prodType: Hardware |
typeDescription: Equipment, tools and parts |
Row 1.1:
categoryName: Bolts |
categoryDescription: Metric & US Sizes |
Row 1.1.1:
itemSKU: 1392610 |
itemDescription: 1/4-20 x 1/2 Grade 8 Hex |
itemPrice: 11.99 |
vendorUID: A8LN99 |
inventoryCount: 1457 |
Row 2:
prodType: Tools |
typeDescription: Hand and power tools |
Row 2.1:
categoryName: Handtools |
categoryDescription: Hammers, screwdrivers, saws |
Row 2.1.1:
itemSKU: 1582178 |
itemDescription: Acme 20 ounce claw hammer |
itemPrice: 24.98 |
vendorUID: D6BQ27 |
inventoryCount: 249 |
from nosqldb import Factory from nosqldb import IllegalArgumentException from nosqldb import ProxyConfig from nosqldb import StoreConfig from nosqldb import ONDB_INCLUDED_TABLES import logging import os import sys # locations where our store and proxy can be found kvlite = 'localhost:5000' proxy = 'localhost:7010' # set logging level to debug and log to stdout def setup_logging(): rootLogger = logging.getLogger() rootLogger.setLevel(logging.DEBUG) logger = logging.StreamHandler(sys.stdout) logger.setLevel(logging.DEBUG) formatter = logging.Formatter('\t%(levelname)s - %(message)s') logger.setFormatter(formatter) rootLogger.addHandler(logger) # configure and open the store def open_store(): kvstoreconfig = StoreConfig('kvstore', [kvlite]) return Factory.open(proxy, kvstoreconfig) def display_row(row): try: ## Our code must track which table we are displaying. ## Use get_table_name() for this purpose. if row.get_table_name() == 'prodTable': print "\nType: %s" % row['prodType'] print "Description: %s" % row['typeDescription'] elif row.get_table_name() == 'prodTable.prodCategory': print "\tCategory: %s" % row['categoryName'] print "\tDescription: %s" % row['categoryDescription'] else: print "\t\tSKU: %s" % row['itemSKU'] print "\t\tDescription: %s" % row['itemDescription'] print "\t\tPrice: %s" % row['itemPrice'] print "\t\tVendor UID: %s" % row['vendorUID'] print "\t\tInventory Count: %s" % row['inventoryCount'] except KeyError, ke: logging.error("Row display failed. Bad key: %s" % ke.message) def do_store_ops(store): try: key_d = {} ## Identify the child tables to include in the retrieval. incTables = ["prodTable.prodCategory", "prodTable.prodCategory.item"] mro = {ONDB_INCLUDED_TABLES : incTables} row_list = store.table_iterator("prodTable", key_d, False, mro) if not row_list: logging.debug("Table retrieval failed") else: logging.debug("Table retrieval succeeded.") for r in row_list: display_row(r) except IllegalArgumentException, iae: logging.error("Row retrieval failed.") logging.error(iae.message) return except KeyError, ke: logging.error("Row display failed. Bad key: %s" % ke.message) if __name__ == '__main__': setup_logging() store = open_store() do_store_ops(store) store.close()