Re: [pysqlite] Seg Fault Only When Table Contains Data

Rich Shepard <[email protected]> Tue, 3 Jun 2008 12:58:47 -0700 (PDT)
Newsgroups gmane.comp.python.db.pysqlite.user
Message-ID <[email protected]>
On Tue, 3 Jun 2008, Adrian Klaver wrote:

> Thought the problem might be the cursor was selecting too much data for
> the memory available. In your previous message the onSave() function
> showed a query with 33 columns, are we talking about the same thing?

Adrian,

   Yes.

   However, if I manually enter data into a single row and two columns, the
app still seg faults when I try to load it again.

> Without seeing more of the code I am at a loss for an explanation.

   Well, none of this makes any sense to me. I've attached the entire module,
dataPage.py. No matter what I try, I cannot isolate the problem. FWIW,
here's the scheme for the Data table:

CREATE TABLE Data (comp TEXT NOT NULL, subcomp TEXT, var TEXT NOT NULL,
curr1 TEXT, curr2 TEXT, curr3 TEXT, curr4 TEXT, curr5 TEXT, curr6 TEXT, 
curr7 TEXT, curr8 TEXT, curr9 TEXT, curr10 TEXT, curr11 TEXT, curr12 TEXT,
noact TEXT, alt2 TEXT, alt3 TEXT, alt4 TEXT, alt5 TEXT, alt6 TEXT, alt7
TEXT, alt8 TEXT, alt9 TEXT, alt10 TEXT, alt11 TEXT, alt12 TEXT, alt13 TEXT, 
alt14 TEXT, alt15 TEXT, alt16 TEXT, alt17 TEXT, alt18 TEXT,
PRIMARY KEY (comp, subcomp, var));

Rich

-- 
Richard B. Shepard, Ph.D.               |  Integrity            Credibility
Applied Ecosystem Services, Inc.        |            Innovation
<http://www.appl-ecosys.com>     Voice: 503-667-4517      Fax: 503-667-8863

_______________________________________________
list-pysqlite mailing list
list-pysqlite-FR6EJeJVuqdwc357pe9rcyQmJico6nz3epZhswDD4dQ@public.gmane.org
http://itsystementwicklung.de/cgi-bin/mailman/listinfo/list-pysqlite
dataPage.py (text/plain, 8.5 KB)
#!/usr/bin/env python

# FramePanel:modData
"""
  This module has the user interface for the notebook tab named 'Data.'
"""

import wx, config, functions, wx.grid
import floatSpin as FS

from pysqlite2 import dbapi2 as sqlite3
from dbMethods import DBtools
from wx.lib.pubsub import Publisher

"""
Dynamically size the grid. If a project is open, then the number of
rows equals the number of variables. Otherwise, a default value of 1
row

The number of columns allows for 18 alternatives (including the No
Action one), 12 individual sets of values for existing conditions, the
names of components, subcomponents, and variables. That's 33 columns
in all.
"""

class modData(wx.Panel):

  appData = config.appData

  def __init__(self, prnt, ID):
    wx.Panel.__init__(self, prnt, wx.ID_ANY, size=wx.Size(770,440))

    self.SetHelpText('Enter, edit, and remove existing condition data and alternatives here.')

    self.nRows = 1
    self.nCols = 33
    self.flag = 0

    self.colLabels = ['Component', 'Subcomponent', 'Variable', 'Current 1',
               'Current 2', 'Current 3', 'Current 4', 'Current 5',
               'Current 6', 'Current 7', 'Current 8', 'Current 9',
               'Current 10', 'Current 11', 'Current 12', 'No Action',
               'Alt 2', 'Alt 3', 'Alt 4', 'Alt 5', 'Alt 6', 'Alt 7',
               'Alt 8', 'Alt 9', 'Alt 10', 'Alt 11', 'Alt 12', 'Alt 13',
               'Alt 14', 'Alt 15', 'Alt 16', 'Alt 17', 'Alt 18']

    topLevelBox = wx.BoxSizer(wx.VERTICAL)        # Base container for all widgets
    outerBox = wx.BoxSizer(wx.VERTICAL)           # Adds to space around widgets
    buttonBox = wx.BoxSizer(wx.HORIZONTAL)        # For the Save button; allows placement across
    widgetBox = wx.BoxSizer(wx.VERTICAL)          # Holds grid and save button

    # Here's where the grid widget is defined.
    self.dataGrid = wx.grid.Grid(self, size=wx.Size(770,440))
    self.dataGrid.CreateGrid(self.nRows,self.nCols,selmode=wx.grid.Grid.SelectCells)

    for col in range(self.nCols):
      self.dataGrid.SetColLabelValue(col,self.colLabels[col])
      
    self.dataGrid.AutoSizeColumns(setAsMin=True)

    # attribute objects let you keep a set of formatting values
    # in one spot, and reuse them if needed

    self.attr = wx.grid.GridCellAttr()
    self.attr.SetTextColour(wx.BLACK)
    self.attr.SetBackgroundColour(wx.RED)
    self.attr.SetFont(wx.Font(10, wx.ROMAN, wx.NORMAL, wx.BOLD))
    self.dataGrid.SetColLabelAlignment(wx.ALIGN_CENTER, wx.ALIGN_BOTTOM)
    self.dataGrid.SetLabelBackgroundColour('DARKOLIVEGREEN')
    self.dataGrid.SetLabelFont(wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD))
    self.dataGrid.SetLabelTextColour('WHEAT')

    self.dataGrid.SetDefaultCellOverflow(False)
    r = wx.grid.GridCellAutoWrapStringRenderer()
    self.dataGrid.SetCellRenderer(9, 1, r)

    editor = wx.grid.GridCellTextEditor()
    editor.SetParameters('10')
    self.dataGrid.SetCellEditor(0, 4, editor)

    self.moveTo = None
    self.Bind(wx.EVT_IDLE, self.OnIdle)

    self.initButton = wx.Button(self, wx.ID_ANY, 'Initialize')
    self.Bind(wx.EVT_BUTTON, self.SetupInit, self.initButton)
    self.saveButton = wx.Button(self, wx.ID_SAVE, 'Save')
    self.Bind(wx.EVT_BUTTON, self.OnSave, self.saveButton)

    # test all the events
    self.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK, self.OnCellLeftClick)

    self.Bind(wx.grid.EVT_GRID_ROW_SIZE, self.OnRowSize)
    self.Bind(wx.grid.EVT_GRID_COL_SIZE, self.OnColSize)

    self.Bind(wx.grid.EVT_GRID_RANGE_SELECT, self.OnRangeSelect)
    self.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.OnCellChange)
    self.Bind(wx.grid.EVT_GRID_SELECT_CELL, self.OnSelectCell)

    self.Bind(wx.grid.EVT_GRID_EDITOR_CREATED, self.OnEditorCreated)
    self.Bind(wx.grid.EVT_GRID_EDITOR_SHOWN, self.OnEditorShown)
    self.Bind(wx.grid.EVT_GRID_EDITOR_HIDDEN, self.OnEditorHidden)    

    buttonBox.Add((225, 0), 0)
    buttonBox.Add(self.initButton, 0, wx.ALL, 5)
    buttonBox.Add((75, 0), 0)
    buttonBox.Add(self.saveButton, 0, wx.ALL, 5)
    
    widgetBox.Add(self.dataGrid, 0, wx.ALL, 0)
    widgetBox.Add(buttonBox, 0, wx.ALL, 2)
    widgetBox.Add((0, 25), 0)

    outerBox.Add(widgetBox, 1, wx.ALL, 2)
    
    topLevelBox.Add(outerBox, 0, wx.ALL, 10)
    self.SetSizer(topLevelBox)

    Publisher().subscribe(self.loadData, self.appData.projOpen)

  # Methods start here ---------------------------------------------------------  
  def SetupInit(self, event):
    oops = wx.MessageDialog(self, "WARNING! All existing data will be permentaly deleted if you proceed","Initialize Grid",wx.YES_NO|wx.NO_DEFAULT|wx.ICON_EXCLAMATION)
    rtnCode = oops.ShowModal()
    if (rtnCode == wx.ID_NO):
      pass
    else:
      oops.Destroy()
      
    self.dataGrid.ClearGrid()                     # clear display
    self.appData.cur.execute("DELETE from Data")  # erase all table rows
    self.appData.cur.execute("SELECT comp_name, subcomp_name, name from Variable")
    loadList = self.appData.cur.fetchall()
    proper = lambda t: (t[0], t[1], t[2])
    loadList.sort(key = proper)
    self.appData.altData = loadList
    self.flag = 1
    self.loadData(self)
    
  def loadData(self, event):
    if len(self.appData.altData) == 0:
      pass
    else:
      self.nRows = self.GetNumberRows()
      if self.flag == 1:
        self.nCols = 3
      else:
        self.nCols = self.dataGrid.GetNumberCols()
      self.dataGrid.AppendRows(self.nRows-1,True)   # there's one row when invoked
      self.dataGrid.ForceRefresh()
      for r in range(self.nRows):
        for c in range(self.nCols):
          self.dataGrid.SetCellValue(r,c,self.appData.altData[r][c])

  def GetNumberRows(self):
    if self.appData.altData != None:
      self.nRows = len(self.appData.altData)
      return self.nRows
    else:
      return 1

  def OnSave(self, event):
    stmt = """INSERT or REPLACE into Data (comp, subcomp, var, curr1, curr2,
                                           curr3, curr4, curr5, curr6, curr7,
                                           curr8, curr9, curr10, curr11,
                                           curr12, noact, alt2, alt3, alt4,
                                           alt5, alt6, alt7, alt8, alt9, alt10,
                                           alt11, alt12, alt13, alt14, alt15,
                                           alt16, alt17, alt18) values (?,?,?,
                                           ?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,
                                           ?,?,?,?,?,?,?,?,?,?,?,?,?)"""

    for r in range(self.nRows):
      row = []
      for c in range(33):
        row.append(self.dataGrid.GetCellValue(r,c))
      self.appData.cur.execute(stmt,row)
    self.appData.con.commit()

  def OnCellLeftClick(self, evt):
    evt.Skip()

  def OnRowSize(self, evt):
    evt.Skip()

  def OnColSize(self, evt):
    evt.Skip()

  def OnRangeSelect(self, evt):        
    evt.Skip()

  def OnCellChange(self, evt):
    # Show how to stay in a cell that has bad data.  We can't just
    # call SetGridCursor here since we are nested inside one so it
    # won't have any effect.  Instead, set coordinates to move to in
    # idle time.
    value = self.GetCellValue(evt.GetRow(), evt.GetCol())

    if value == 'no good':
      self.moveTo = evt.GetRow(), evt.GetCol()

  def OnIdle(self, evt):
    if self.moveTo != None:
      self.SetGridCursor(self.moveTo[0], self.moveTo[1])
      self.moveTo = None
    evt.Skip()

  def OnSelectCell(self, evt):
    # Another way to stay in a cell that has a bad value...
    row = self.dataGrid.GetGridCursorRow()
    col = self.dataGrid.GetGridCursorCol()

    if self.dataGrid.IsCellEditControlEnabled():
      self.HideCellEditControl()
      self.DisableCellEditControl()

    value = self.dataGrid.GetCellValue(row, col)

    if value == 'no good 2':
      return  # cancels the cell selection

    evt.Skip()

  def OnEditorShown(self, evt):
    if evt.GetRow() == 6 and evt.GetCol() == 3 and \
      wx.MessageBox("Are you sure you wish to edit this cell?",
                    "Checking", wx.YES_NO) == wx.NO:
      evt.Veto()
      return

    evt.Skip()

  def OnEditorHidden(self, evt):
    if evt.GetRow() == 6 and evt.GetCol() == 3 and \
      wx.MessageBox("Are you sure you wish to finish editing this cell?",
                    "Checking", wx.YES_NO) == wx.NO:
      evt.Veto()
      return

    evt.Skip()

  def OnEditorCreated(self, evt):
    evt.Skip()

# end of class modData