ネストされた表の反復使用

表を反復して使用する場合、または複数の取得操作を実行している場合、デフォルトでは操作中の表から行のみが取得されます。ただし、MultiRowOptionsを使用すると、その親表および子表も取得するように指定できます。

これを実行する場合、まず親表が取得され、操作中の表が取得された後、子表が取得されます。つまり、表の階層的順序が順守されます。

取得された親表および子表は、表名のリストを使用して識別され、その後、MultiRowOpetionsオブジェクトのONDB_INCLUDED_TABLESプロパティに指定されます。

複数の表から取得された行を操作する場合、その行が属する表を決定するのはユーザーです。

たとえば、次のような子および孫表を含む表を作成するとします。

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)
) 

次のようなデータを含む表:

  • 行1:

    • prodType: Hardware

    • typeDescription: Equipment、toolsおよびparts

    • 行1.1:

      • categoryName: Bolts

      • categoryDescription: Metric & US Sizes

      • 行1.1.1:

        • itemSKU: 1392610

        • itemDescription: 1/4-20 x 1/2 Grade 8 Hex

        • itemPrice: 11.99

        • vendorUID: A8LN99

        • inventoryCount: 1457

  • 行2:

    • prodType: Tools

    • typeDescription: Handおよびpower tools

    • 行2.1:

      • categoryName: Handtools

      • categoryDescription: Hammers、screwdrivers、saws

      • 行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()