Fresh Eyeballs Needed to See Error

Rich Shepard rshepard at appl-ecosys.com
Fri Nov 3 13:19:47 PST 2006


   Now that I have the variable 'projname' visible among modules, I'm trying
to find why one specific module cannot find an attribute in an imported
class. Other modules find it and order of listing the import statements does
not affect the error generation on this one page. No matter how many times I
look, I don't see what's different.

   File "/data1/eikos/policyPage.py", line 135, in setUpTree
     DBtools.cur.execute("select * from component where category='natural';")
AttributeError: class DBtools has no attribute 'cur'

   The class DBtools does have the sqlite cursor attribute, and two other
modules (the main application one and another notebook page) use the same
reference without a complaint.

   policyPage.py and dbMethods.py are attached.

TIA,

Rich

-- 
Richard B. Shepard, Ph.D.               |    The Environmental Permitting
Applied Ecosystem Services, Inc.(TM)    |            Accelerator
<http://www.appl-ecosys.com>     Voice: 503-667-4517      Fax: 503-667-8863
-------------- next part --------------
#!/usr/bin/env python

import wx
import config

from pysqlite2 import dbapi2 as sqlite3

class DBtools:
  
  dbFileName = config.projname + '.db'
  
  def OnOpenDB(self, dbFileName):
    """
    Open the database connection if not already opened
    """
    con = None
    cur = None

    if not con:
      self.con = sqlite3.connect(dbFileName)
      self.cur = self.con.cursor()

      # create schema if first use
      try:
        self.cur.execute("select * from model")
      except sqlite3.OperationalError, e:
        if str(e).startswith("no such table"):
          """ Overall model information """
          self.cur.execute("CREATE TABLE model (model_name TEXT NOT NULL PRIMARY KEY, \
                            model_desc TEXT, model_type TEXT, keName TEXT, agent INTEGER);")
          
          """ Scoping: categories of natural, ecomonic, societal
              These categories are hard-coded as they are the same for all
              environmental impact assessments."""
          self.cur.execute("CREATE TABLE category (cat_name TEXT NOT NULL PRIMARY KEY);")
          self.cur.execute("insert into category (cat_name) values ('natural');")
          self.cur.execute("insert into category (cat_name) values ('economic');")
          self.cur.execute("insert into category (cat_name) values ('societal');")
          
          """ Scoping: candidate components within a category"""
          self.cur.execute("CREATE TABLE component (comp_id integer primary key, \
                            comp_cat TEXT, comp_name TEXT);")
          
          """ On Insert of a component """
          self.cur.execute("CREATE TRIGGER fki_comp_cat \
                            BEFORE INSERT ON component \
                            FOR EACH ROW \
                            BEGIN \
                              SELECT CASE \
                                WHEN NEW.comp_cat IS NOT NULL AND \
                                (SELECT cat_name FROM category \
                                 WHERE cat_name = NEW.comp_cat) IS NULL \
                                THEN RAISE(ROLLBACK, 'insert on table category violates \
                                foreign key constraint fk_comp_cat') \
                              END; \
                            END;")
          
          """ On Update of a component """
          self.cur.execute("CREATE TRIGGER fku_comp_cat \
                            BEFORE UPDATE ON component \
                            FOR EACH ROW \
                            BEGIN \
                              SELECT CASE \
                                WHEN NEW.pair_cat IS NOT NULL AND \
                                (SELECT cat_name FROM category WHERE \
                                 cat_name = NEW.comp_cat) IS NULL \
                                THEN RAISE(ROLLBACK, 'update on table component \
                                violates foreign key constraint fk_comp_cat') \
                              END; \
                            END;")

          """ On Delete of a category """
          self.cur.execute("CREATE TRIGGER fkd_comp_cat \
                            BEFORE DELETE ON category \
                            FOR EACH ROW \
                            BEGIN \
                              SELECT CASE \
                                WHEN (SELECT COUNT (comp_cat) from component WHERE \
                                comp_cat = OLD.cat_name) > 0 \
                                THEN RAISE(ABORT, 'Foreign Key Violation: component \
                                rows references row to be deleted.') \
                              END; \
                            END;")
          
          """ Scoping: pairs of components for voting.
              The three fields are for the category, the first component of the
              pair, and the second component of the pair."""
          self.cur.execute("CREATE TABLE pairs (pair_id integer primary key, \
                            pair_cat TEXT, comp1 text, comp2 test);")
 
          """ On Insert of a component pair"""
          self.cur.execute("CREATE TRIGGER fki_pair_cat \
                            BEFORE INSERT ON pairs \
                            FOR EACH ROW \
                            BEGIN \
                              SELECT CASE \
                              WHEN NEW.pair_cat IS NOT NULL AND \
                              (SELECT cat_name FROM category WHERE \
                                    cat_name = NEW.pair_cat) IS NULL \
                              THEN RAISE(ROLLBACK, 'insert on table pairs \
                                    violates foreign key constraint fk_pair_cat') \
                              END; \
                            END;")
          
          """ On Update of a component pair """
          self.cur.execute("CREATE TRIGGER fku_pair_cat \
                            BEFORE UPDATE ON pairs \
                            FOR EACH ROW \
                            BEGIN \
                              SELECT CASE \
                              WHEN NEW.pair_cat IS NOT NULL AND \
                              (SELECT cat_name FROM category WHERE \
                                cat_name = NEW.pair_name) IS NULL \
                              THEN RAISE(ROLLBACK, 'update on table component \
                                violates foreign key constraint fk_pair_cat') \
                              END; \
                            END;")

          
          """ Voting: a record for each card scanned in rating the pairs by
              category """
          self.cur.execute("CREATE TABLE voting (vote_id INTEGER PRIMARY KEY, \
                                                  cat TEXT, pos TEXT, pr1 REAL, pr2 REAL, \
                                                  pr3 REAL, pr4 REAL, pr5 REAL, pr6 REAL, \
                                                  pr7 REAL, pr8 REAL, pr9 REAL, pr10 REAL, \
                                                  pr11 REAL, pr12 REAL, pr13 REAL, \
                                                  pr14 REAL, pr15 REAL, pr16 REAL, \
                                                  pr17 REAL, pr18 REAL, pr19 REAL, \
                                                  pr20 REAL, pr21 REAL, pr22 REAL, \
                                                  pr23 REAL, pr24 REAL, pr25 REAL, \
                                                  pr26 REAL, pr27 REAL, pr28 REAL);")

          """ Scoping: eigenvector of importance weights """
          self.cur.execute("CREATE TABLE importance (imp_id integer primary key, \
                            comp_name TEXT, imp_weight REAL);")
          
          """ Policies that encapsulate related variables """
          self.cur.execute("CREATE TABLE policy (pol_id integer primary key, \
                            policy_name TEXT NOT NULL, policy_comp TEXT);")

          """ On Insert of a policy """
          self.cur.execute("CREATE TRIGGER fki_policy_name \
                            BEFORE INSERT ON policy \
                            FOR EACH ROW \
                            BEGIN \
                              SELECT CASE \
                               WHEN NEW.policy_name IS NOT NULL AND \
                               (SELECT comp_name FROM components WHERE \
                                    comp_name = NEW.policy_name) IS NULL \
                               THEN RAISE(ROLLBACK, 'insert on table policy \
                                    violates foreign key constraint fk_policy_name') \
                               END; \
                             END;")
          
          """ On Update of a policy """
          self.cur.execute("CREATE TRIGGER fku_policy_name \
                            BEFORE UPDATE ON policy \
                            FOR EACH ROW \
                            BEGIN \
                            SELECT CASE \
                              WHEN NEW.policy_name IS NOT NULL \
                              AND (SELECT comp_name FROM category WHERE \
                                  comp_name = NEW.policy_name) IS NULL \
                              THEN RAISE(ROLLBACK, 'update on table policy \
                                  violates foreign key constraint fk_policy_name') \
                              END; \
                            END;")

          """ On Delete of a category """
          self.cur.execute("CREATE TRIGGER fkd_policy_comp \
                            BEFORE DELETE ON component \
                            FOR EACH ROW \
                            BEGIN \
                              SELECT CASE \
                              WHEN (SELECT count(policy_comp) from component WHERE \
                              policy_comp = OLD.comp_name) \
                              THEN RAISE (ABORT, 'Foreign Key Violation: component \
                                 row references row to be deleted') \
                              END; \
                            END;")
          
          """ Subpolicies allow finer resolution chunks of variables """
          self.cur.execute("CREATE TABLE subpolicy (subpol_id integer primary key, \
                            sub_policy_name text, policy_name text);")
          
          self.cur.execute("CREATE INDEX sub_pol_idx ON subpolicy(sub_policy_name, \
                                         policy_name);")

          """ Variables are the basic units of analysis in the model """
          self.cur.execute("CREATE TABLE variable (variable_name TEXT NOT NULL PRIMARY KEY, \
                                                    variable_descript TEXT, \
                                                    variable_data_source TEXT, \
                                                    variable_scale REAL, \
                                                    variable_defuzzify TEXT, \
                                                    variable_UoD_low REAL, \
                                                    variable_UoD_high REAL, \
                                                    variable_alpha_cut REAL, \
                                                    variable_alpha_type TEXT, \
                                                    variable_termset_num INTEGER, \
                                                    variable_consequent_geom TEXT, \
                                                    variable_correlation_method TEX, \
                                                    variable_implication_method TEXT);")
                                                   

          """ Fuzzy sets repreent the terms within each linguistic variable """
          self.cur.execute("CREATE TABLE fuzzyset (fuzzy_set_name TEXT NOT NULL PRIMARY KEY, \
                                                    variable_name TEXT, \
                                                    fuzzy_set_low REAL, \
                                                    fuzzy_set_inflect_pt REAL, \
                                                    fuzzy_set_high REAL, \
                                                    fuzzy_set_alpha_cut REAL, \
                                                    fuzzy_set_curve TEXT);")
          
          self.cur.execute("CREATE INDEX fuz_set_idx on fuzzyset(fuzzy_set_name, variable_name);")

          """ Hedges """
          self.cur.execute("CREATE TABLE hedge (hedge_id integer primary key, \
                                                hedge_name TEXT, hedge_effect TEXT);")
          self.cur.execute("insert into hedge (hedge_name) values ('around');")
          self.cur.execute("insert into hedge (hedge_name) values ('slightly');")
          self.cur.execute("insert into hedge (hedge_name) values ('not');")
          self.cur.execute("insert into hedge (hedge_name) values ('near');")
          self.cur.execute("insert into hedge (hedge_name) values ('positively');")
          self.cur.execute("insert into hedge (hedge_name) values ('above');")
          self.cur.execute("insert into hedge (hedge_name) values ('after');")
          self.cur.execute("insert into hedge (hedge_name) values ('before');")
          self.cur.execute("insert into hedge (hedge_name) values ('below');")
          self.cur.execute("insert into hedge (hedge_name) values ('generally');")
          self.cur.execute("insert into hedge (hedge_name) values ('vicinity');")
          self.cur.execute("insert into hedge (hedge_name) values ('very');")
          self.cur.execute("insert into hedge (hedge_name) values ('somewhat');")
          self.cur.execute("insert into hedge (hedge_name) values ('extremely');")
          self.cur.execute("insert into hedge (hedge_name) values ('about');")
          self.cur.execute("insert into hedge (hedge_name) values ('close');")
          
          """ Noise Words """
          self.cur.execute("CREATE TABLE noisewds (nw_id integer primary key, \
                                                   noiseword TEXT);")
          self.cur.execute("insert into noisewds (noiseword) values ('could');")
          self.cur.execute("insert into noisewds (noiseword) values ('might');")
          self.cur.execute("insert into noisewds (noiseword) values ('a');")
          self.cur.execute("insert into noisewds (noiseword) values ('than');")
          self.cur.execute("insert into noisewds (noiseword) values ('they');")
          self.cur.execute("insert into noisewds (noiseword) values ('may');")
          self.cur.execute("insert into noisewds (noiseword) values ('ought');")
          self.cur.execute("insert into noisewds (noiseword) values ('should');")
          self.cur.execute("insert into noisewds (noiseword) values ('that');")
          self.cur.execute("insert into noisewds (noiseword) values ('would');")
          self.cur.execute("insert into noisewds (noiseword) values ('these');")
          self.cur.execute("insert into noisewds (noiseword) values ('our');")
          self.cur.execute("insert into noisewds (noiseword) values ('those');")
          self.cur.execute("insert into noisewds (noiseword) values ('will');")
          self.cur.execute("insert into noisewds (noiseword) values ('an');")
          self.cur.execute("insert into noisewds (noiseword) values ('this');")
          self.cur.execute("insert into noisewds (noiseword) values ('the');")

          """ Rules As Written """
          self.cur.execute("CREATE TABLE rules (rule_num INTEGER PRIMARY KEY, \
                                                 rule_string TEXT NOT NULL, \
                                                 variable_name TEXT);")

          """ Rule tokens after parsing and before compiling """
          self.cur.execute("CREATE TABLE rule_token (rule_num INTEGER, token_num INTEGER, \
                                                      token_name TEXT, \
                                                      token_len INTEGER, \
                                                      token_type TEXT, \
                                                      token_sym_value TEXT, \
                                                      primary key (rule_num, token_num));")

          """ On Insert of a rule token """
          self.cur.execute("CREATE TRIGGER fki_rule_token \
                            BEFORE INSERT ON rule_token \
                            FOR EACH ROW \
                            BEGIN \
                              SELECT CASE \
                              WHEN NEW.token_num IS NOT NULL AND \
                              (SELECT rule_num FROM rules WHERE \
                                    token_nuk = NEW.rule_num) IS NULL \
                              THEN RAISE (ROLLBACK, 'insert on table rules \
                                    violates foreign key constraint fk_rule_tok') \
                              END; \
                            END;")
          
          """ On Update of a rule token """
          self.cur.execute("CREATE TRIGGER fku_rule_token \
                            BEFORE UPDATE ON rule_token \
                            FOR EACH ROW \
                            BEGIN \
                              SELECT CASE \
                              WHEN NEW.token_num IS NOT NULL AND \
                              (SELECT rule_num FROM rules WHERE \
                                token_num = NEW.rule_num) IS NULL \
                              THEN RAISE(ROLLBACK, 'update on table rule_token \
                                violates foreign key constraint fk_rule_tok') \
                              END; \
                            END;")

          """ On Delete of a rule """
          self.cur.execute("CREATE TRIGGER fkd_rule \
                            BEFORE DELETE ON rules \
                            FOR EACH ROW \
                            BEGIN \
                              SELECT CASE \
                              WHEN (SELECT count(token_num) from rules WHERE \
                              token_num = OLD.rule_num) \
                              THEN RAISE (ABORT, 'Foreign Key Violation: rule row \
                              references row to be deleted') \
                              END; \
                            END;")

  def OnCloseDb(self):
    """
    Closes the database connection explicitly.
    """
    self.cur.close()
    self.con.close()
 
-------------- next part --------------
#FramePanel:modPolicy
"""
  This module has the user interface for the notebook tab named 'Policy.'
  """

import wx
import config

from pysqlite2 import dbapi2 as sqlite3
from dbMethods import DBtools

class modPolicy(wx.Panel):
  """ Policies may have sub-policies, and either will have variables assigned.
  The policies and sub-policies are displayed in a tree and the user can add
  policies and sub-policies by clicking on the add button.

  Variables are displayed in a text control and can be assigned to or deleted from
  policies/sub-policies by the user, but only after being defined in the variables page.

  To add a new policy, use the Add button. To add a subpolicy, highlight the parent policy
  before using the Add button. To edit a policy or subpolicy, select it by right-clicking
  on the name. You can edit it in place.
  """
  
  def __init__(self, prnt, ID):
    wx.Panel.__init__(self, prnt, wx.ID_ANY)

    self.SetClientSize(wx.Size(800, 600))

    topSizer = wx.BoxSizer(wx.VERTICAL)     # main container
    policyBox = wx.BoxSizer(wx.VERTICAL)    # list of poicies/sub-policies & buttons
    variableBox = wx.BoxSizer(wx.VERTICAL)  # list of variables in each policy & buttons
    sidewaysBox = wx.BoxSizer(wx.HORIZONTAL)  # for the policy and variable boxes

    """ Top row: policy tree and list of components.
    The list of policies comes from the component table; if not all components are
    included in the assessment, then they are deleted from the tree list and removed at
    next save into the policy table.
    """
    
    policyName = wx.StaticText(self, wx.ID_ANY, "Policies/Sub-Policies")

    self.polTree = wx.TreeCtrl(self, wx.ID_ANY, size=wx.Size(220, 225), style=wx.RAISED_BORDER|
                             wx.TR_EDIT_LABELS|wx.TR_HAS_BUTTONS)
    
    self.rootID = self.polTree.AddRoot('Policies')
 
    self.Bind(wx.EVT_TREE_BEGIN_LABEL_EDIT, self.OnPolEdit)
    self.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.OnEndEdit)
    self.Bind(wx.EVT_TREE_DELETE_ITEM, self.OnPolDel)

    policyBox.Add(policyName, 0, wx.ALIGN_CENTER_HORIZONTAL)
    policyBox.Add(self.polTree, 1, wx.ALIGN_CENTER_HORIZONTAL)
   
    varName = wx.StaticText(self, wx.ID_ANY, "Variables")

    varList = wx.ListBox(self, wx.ID_ANY, size=wx.Size(200, 225), style=wx.LB_SINGLE|
                               wx.LB_NEEDED_SB)

    variableBox.Add(varName, 0, wx.ALIGN_CENTER_HORIZONTAL)
    variableBox.Add(varList, 1, wx.ALIGN_CENTER_HORIZONTAL)

    # Bottom row: buttons for policies and variables
    
    addPolButton = wx.Button(self, wx.ID_ANY, label='Add Policy', size=wx.Size(125,25),
                             style=wx.RAISED_BORDER)
    self.SetHelpText('Add a policy to the model')
    self.Bind(wx.EVT_BUTTON, self.OnPolAdd, addPolButton)

    addSubPolButton = wx.Button(self, wx.ID_ANY, label='Add Sub-Policy', size=wx.Size(125,25),
                                style=wx.RAISED_BORDER)
    self.SetHelpText('Add a sub-policy')
    self.Bind(wx.EVT_BUTTON, self.OnSubPolAdd, addSubPolButton)
    
    delPolButton = wx.Button(self, wx.ID_ANY, label='Delete Policy', size=wx.Size(125,25),
                             style=wx.RAISED_BORDER)
    self.SetHelpText('Delete a policy')
    self.Bind(wx.EVT_BUTTON, self.OnPolDel, delPolButton)
    
    policyBox.Add(addPolButton, 0, wx.ALIGN_CENTER|wx.ALL, 5)
    policyBox.Add(addSubPolButton, 0, wx.ALIGN_CENTER|wx.ALL, 5)
    policyBox.Add(delPolButton, 0, wx.ALIGN_CENTER|wx.ALL, 5)

    """
    addVarButton = wx.Button(self, wx.ID_ANY, label='Add Variable', size=wx.Size(125,25),
                             style=wx.RAISED_BORDER)
    self.SetHelpText('Add a variable to the policy')
    self.Bind(wx.EVT_BUTTON, self.OnVarAdd, addVarButton)
    
    delVarButton = wx.Button(self, wx.ID_ANY, label='Delete Variable', size=wx.Size(125,25),
                             style=wx.RAISED_BORDER)
    self.SetHelpText('Delete variable from the policy')
    self.Bind(wx.EVT_BUTTON, self.OnVarDel, delVarButton)
    """
    
    storeButton = wx.Button(self, wx.ID_ANY, label='Store', size=wx.Size(125,25),
                            style=wx.RAISED_BORDER)
    self.SetHelpText('Store policies and variables')
    self.Bind(wx.EVT_BUTTON, self.OnStore, storeButton)

    # variableBox.Add(addVarButton, 0, wx.ALIGN_CENTER|wx.ALL, 5)
    # variableBox.Add(delVarButton, 0, wx.ALIGN_CENTER|wx.ALL, 5)
    variableBox.Add(storeButton, 0, wx.ALIGN_CENTER|wx.ALL, 5)

    divider = wx.StaticLine(self, wx.ID_ANY, size=wx.Size(-1, 485), style=wx.LI_VERTICAL)

    sidewaysBox.Add(policyBox, 1, wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 15)
    sidewaysBox.Add(divider, 0, wx.EXPAND)
    sidewaysBox.Add(variableBox, 1, wx.EXPAND|wx.ALIGN_CENTER_HORIZONTAL|wx.ALL, 15)

    topSizer.Add(sidewaysBox, 1, wx.EXPAND|wx.ALL, 5)
    
    self.SetSizerAndFit(topSizer)

    self.setUpTree()

  " Event Handlers Follow "
  
  def setUpTree(self):
    """
    Here enter the categories as top-level items, and components as second-level
    items. The latter come from the 'component' table in the project database. So,
    open a cursor, read the components by category into a list, then insert them
    into the tree under the appropirate category. These are not user editable. The
    user can enter policies and sub-policies under the appropriate component.
    """

    # top level below the tree root
    natID = self.polTree.AppendItem(self.rootID, 'Natural')
    ecoID = self.polTree.AppendItem(self.rootID, 'Economic')
    socID = self.polTree.AppendItem(self.rootID, 'Societal')

    # next level below the tree root
    natComp = []
    DBtools.cur.execute("select * from component where category='natural';")
    """    
    row = DBtools.cur.fetchone()
    while row:
      natComp = row[2]
      # get next row
      row = DBtools.cur.fetchone()
    for x in natComp:
      polID = self.polTree.AppendItem(self.natID, 'x')

    ecoComp = []
    DBtools.cur.execute("select * from component where category='economic';")
    row = cur.fetchone()
    while row:
      ecoComp = row[2]
      # get next row
      row = cur.fetchone()
    for x in ecoComp:
      polID = self.polTree.AppendItem(self.ecoID, 'x')

    socComp = []
    DBtools.cur.execute("select * from component where category='societal';")
    row = cur.fetchone()
    while row:
      socComp = row[2]
      # get next row
      row = cur.fetchone()
    for x in socComp:
      polID = self.polTree.AppendItem(self.socID, 'x')
      """

  def OnPolEdit(self, event):
    item = event.GetItem()
    if item and self.tree.GetItemText(item) == "The Root Item":
      wx.Bell()
      # Lets just see what's visible of its children
      cookie = 0
      root = event.GetItem()
      (child, cookie) = self.tree.GetFirstChild(root)

      while child.IsOk():
        (child, cookie) = self.tree.GetNextChild(root, cookie)
    
  def OnEndEdit(self, event):
    self.SetItemText(polID)

  def OnPolDel(self, event):
    self.Delete(polID)

  def OnPolAdd(self, event):
    newPol = wx.TextEntryDialog(self, 'Add Policy Name:',
                                'Policy Name', style=wx.OK|wx.CANCEL|wx.CENTER)
    txt = None
    if (newPol.ShowModal() == wx.ID_OK):
      txt = newPol.GetValue()
      polID = self.polTree.AppendItem(self.rootID, 'txt')
    else:
      txt = ' '
    newPol.Destroy()
    
  def OnSubPolAdd(self, event):
    txt = None
    parent = self.polTree.GetCount()
    if parent == 1:    # only the root node is present
      retCode = wx.MessageBox('Need policy before adding sub-policy.','Oops!',
                              wx.OK | wx.ICON_ERROR | wx.CENTER)
      return(retCode)
    newSubPol = wx.TextEntryDialog(self, 'Add Sub-Policy name:',
                                'Sub-Policy Name', style=wx.OK|wx.CANCEL|wx.CENTER)

    if (newSubPol.ShowModal() == wx.ID_OK):
      txt = newSubPol.GetValue()
      subPolID = self.polTree.AppendItem(self.polID, 'txt')
      newSubPol.Destroy()

  def OnStore(self, event):
    """
    Need to walk the tree control and put policies (with their parent component)
    into the policy table, and subpolicies into the subpolicy table. Go figure out
    how to do all this.
    """
    # DBtools.cur.execute('insert into policy (
    pass
  


More information about the wxpython-users mailing list