Saving grid changes to a database

Hello,

I'm new to wxPython. I have write a simple app that reads data from a
postgres database using PyGridTableBase class. The problem is that I
would like to save the changes that I made on to the grid's cells to
the database. I would like to achive the same functionality that is
used with the pgAdmin3 grid's to edit a table. I mean that when I
change the value of a cell that value is saved/updated to the
database.

How can I do this???

Thanks in advance

Salbefe,

If you have a lot of data binding requirements, you may want to take a
look at the open source Dabo framework which is built on top of
wxPython.

www.dabodev.com

Malcolm

If you don't go the Dabo route, then I think you would want to use the
grid events. For example, EVT_GRID_CELL_CHANGE is triggered when the
user changes the data in a cell via an editor, so you could use that
to know when to update the database.

···

On Dec 14, 7:12 pm, salbefe <salb...@gmail.com> wrote:

Hello,

I'm new to wxPython. I have write a simple app that reads data from a
postgres database using PyGridTableBase class. The problem is that I
would like to save the changes that I made on to the grid's cells to
the database. I would like to achive the same functionality that is
used with the pgAdmin3 grid's to edit a table. I mean that when I
change the value of a cell that value is saved/updated to the
database.

How can I do this???

Thanks in advance

-------------------
Mike Driscoll

Blog: http://blog.pythonlibrary.org

I take it you've made a class that inherits from PyGridTableBase, and to read the data out of the database you've overridden the GetValue() method. Well, to write back to the database, you should override the SetValue() method.
   If this doesn't help, post some code here so people can see what you're doing.

Paul Probert

···

On 12/14/2010 07:12 PM, salbefe wrote:

Hello,

I'm new to wxPython. I have write a simple app that reads data from a
postgres database using PyGridTableBase class. The problem is that I
would like to save the changes that I made on to the grid's cells to
the database. I would like to achive the same functionality that is
used with the pgAdmin3 grid's to edit a table. I mean that when I
change the value of a cell that value is saved/updated to the
database.

How can I do this???

Thanks in advance

Thanks all,

This is the code from the class that inherits PyGridTableBase:

class myGrid(wx.grid.Grid):

    def __init__(self,parent,ID,size,connection):
        wx.grid.Grid.__init__(self,parent,ID,size)

  self.connection = connection
  self.numRegistros = 30

        ##getData = Select colA,colB,colC,colD,colE,colF from
datastation where id_station=3 order by id desc

        self.data = self.getData(self.numRegistros,self.connection)
  self.data_table = DataGrid(self.data)
  self.SetTable(self.data_table)

class DataGrid(wx.grid.PyGridTableBase):

    colLabels = ("COL A","COL B","COL C","COL D","COL E","COL F")

    def __init__(self,data):
  wx.grid.PyGridTableBase.__init__(self)

  ##Atributos de la clase
  self.data = data

    def GetNumberRows(self):
  return len(self.data)

    def GetNumberCols(self):
  return 6

    def GetColLabelValue(self, col):
  return self.colLabels[col]

    def GetRowLabelValue(self, row):
  return row+1

    def IsEmptyCell(self, row, col):
  return False

    def GetValue(self, row, col):
  if col in range(0,4):
      return locale.format("%.*f",(4,self.data[row][col]),True)
  else:
      return self.data[row][col]

    def SetValue(self, row, col, value):
  pass

    def UpdateDataModel(self, newdata):
        # ... set new data ...
        self.GetView().BeginBatch()

  newNumRows = len(newdata)
  curNumRows = self.GetNumberRows()
  newNumCols = 6
  curNumCols = 6

  if newNumRows < curNumRows:
            msg = wx.grid.GridTableMessage(self,
                        wx.grid.GRIDTABLE_NOTIFY_ROWS_DELETED,
                        curNumRows - newNumRows, # position
                        curNumRows - newNumRows) # how many
            self.GetView().ProcessTableMessage(msg)
        if newNumRows > curNumRows:
            msg = wx.grid.GridTableMessage(self,
                        wx.grid.GRIDTABLE_NOTIFY_ROWS_APPENDED,
                        newNumRows - curNumRows) # how many
            self.GetView().ProcessTableMessage(msg)

        # ... same thing for columns ....

        self.GetView().EndBatch()

  self.data = newdata
        msg = wx.grid.GridTableMessage(self,
wx.grid.GRIDTABLE_REQUEST_VIEW_GET_VALUES)
        self.GetView().ProcessTableMessage(msg)

I do not know how I should use the SetValue() or the code I should put
when EVT_GRID_CELL_CHANGE is triggered to write back the data to the
database because:

1.- The data that is passed to the class above does not have a "ID
column" because the grid should not show that "ID column". I do not
know how I can do and update of a value.
2.- New rows can be inserted by the user. How do I know when I should
do an update of a value or a new insert in the datatable??

Thanks in advance

···

On 16 dic, 05:50, Paul Probert <paulprob...@sbcglobal.net> wrote:

On 12/14/2010 07:12 PM, salbefe wrote:> Hello,

> I'm new to wxPython. I have write a simple app that reads data from a
> postgres database using PyGridTableBase class. The problem is that I
> would like to save the changes that I made on to the grid's cells to
> the database. I would like to achive the same functionality that is
> used with the pgAdmin3 grid's to edit a table. I mean that when I
> change the value of a cell that value is saved/updated to the
> database.

> How can I do this???

> Thanks in advance

I take it you've made a class that inherits from PyGridTableBase, and to
read the data out of the database you've overridden the GetValue()
method. Well, to write back to the database, you should override the
SetValue() method.
If this doesn't help, post some code here so people can see what
you're doing.

Paul Probert

Thanks all,

This is the code from the class that inherits PyGridTableBase:

class myGrid(wx.grid.Grid):

     def __init__(self,parent,ID,size,connection):
         wx.grid.Grid.__init__(self,parent,ID,size)

  self.connection = connection
  self.numRegistros = 30

         ##getData = Select colA,colB,colC,colD,colE,colF from
datastation where id_station=3 order by id desc

         self.data = self.getData(self.numRegistros,self.connection)
  self.data_table = DataGrid(self.data)
  self.SetTable(self.data_table)

class DataGrid(wx.grid.PyGridTableBase):

     colLabels = ("COL A","COL B","COL C","COL D","COL E","COL F")

     def __init__(self,data):
  wx.grid.PyGridTableBase.__init__(self)

  ##Atributos de la clase
  self.data = data

     def GetNumberRows(self):
  return len(self.data)

     def GetNumberCols(self):
  return 6

     def GetColLabelValue(self, col):
  return self.colLabels[col]

     def GetRowLabelValue(self, row):
  return row+1

     def IsEmptyCell(self, row, col):
  return False

     def GetValue(self, row, col):
  if col in range(0,4):
      return locale.format("%.*f",(4,self.data[row][col]),True)
  else:
      return self.data[row][col]

     def SetValue(self, row, col, value):
  pass

     def UpdateDataModel(self, newdata):
         # ... set new data ...
         self.GetView().BeginBatch()

  newNumRows = len(newdata)
  curNumRows = self.GetNumberRows()
  newNumCols = 6
  curNumCols = 6

  if newNumRows< curNumRows:
             msg = wx.grid.GridTableMessage(self,
                         wx.grid.GRIDTABLE_NOTIFY_ROWS_DELETED,
                         curNumRows - newNumRows, # position
                         curNumRows - newNumRows) # how many
             self.GetView().ProcessTableMessage(msg)
         if newNumRows> curNumRows:
             msg = wx.grid.GridTableMessage(self,
                         wx.grid.GRIDTABLE_NOTIFY_ROWS_APPENDED,
                         newNumRows - curNumRows) # how many
             self.GetView().ProcessTableMessage(msg)

         # ... same thing for columns ....

         self.GetView().EndBatch()

  self.data = newdata
         msg = wx.grid.GridTableMessage(self,
wx.grid.GRIDTABLE_REQUEST_VIEW_GET_VALUES)
         self.GetView().ProcessTableMessage(msg)

I do not know how I should use the SetValue() or the code I should put
when EVT_GRID_CELL_CHANGE is triggered to write back the data to the
database because:

1.- The data that is passed to the class above does not have a "ID
column" because the grid should not show that "ID column". I do not
know how I can do and update of a value.

I have two columns in my grid for my db table primary keys and hide these columns, so user can't see them.

2.- New rows can be inserted by the user. How do I know when I should
do an update of a value or a new insert in the datatable??

Isn't there a specific event when one inserts a new row? I don't use it as new entries are done with a dialog and not directly in the grid.

Werner

···

On 16/12/2010 13:10, salbefe wrote:

Le 16/12/2010 14:50, werner a �crit :

2.- New rows can be inserted by the user. How do I know when I should
do an update of a value or a new insert in the datatable??

Isn't there a specific event when one inserts a new row? I don't use it as new entries are done with a dialog and not directly in the grid.

Werner

At the beginning of SetValue, I do :

         try :
             key = self.data[row][0]
         except IndexError :
             self.data.append(self.vide[:])
             msg = wx.grid.GridTableMessage(self, \
                   wx.grid.GRIDTABLE_NOTIFY_ROWS_APPENDED, 1)
             self.GetView().ProcessTableMessage(msg)
             key = ''
         if key :
             # Update
         else :
             # Insert

Exactly, I put all modifications of the grid in a list and when the user click the validate button, I do all the Insert and Update

···

--

Hugues JEAN-BAPTISTE (hjb@agorinfo.fr)
AGORINFO S.A.S. (http://www.agorinfo.fr)

I think you're not understanding the idea of pygridtablebase and what happens when you define SetValue. You're overriding a method, and the grid will then call your method when the user changes a value in the grid.
   Change your SetValue to this:

       def SetValue(self, row, col, value):
    print 'in SetValue, row=',row,' col=',col,' value=',value

Does this print when the user edits a cell?
Likewise, for inserting or deleting a row, there are methods to override for these actions too.

It seems you must have found it, but just in case, the place to look is in the wiki wxPyGridTableBase - wxPyWiki

Paul Probert

···

On 12/16/2010 06:10 AM, salbefe wrote:

Thanks all,

This is the code from the class that inherits PyGridTableBase:

class myGrid(wx.grid.Grid):

     def __init__(self,parent,ID,size,connection):
         wx.grid.Grid.__init__(self,parent,ID,size)

  self.connection = connection
  self.numRegistros = 30

         ##getData = Select colA,colB,colC,colD,colE,colF from
datastation where id_station=3 order by id desc

         self.data = self.getData(self.numRegistros,self.connection)
  self.data_table = DataGrid(self.data)
  self.SetTable(self.data_table)

class DataGrid(wx.grid.PyGridTableBase):

     colLabels = ("COL A","COL B","COL C","COL D","COL E","COL F")

     def __init__(self,data):
  wx.grid.PyGridTableBase.__init__(self)

  ##Atributos de la clase
  self.data = data

     def GetNumberRows(self):
  return len(self.data)

     def GetNumberCols(self):
  return 6

     def GetColLabelValue(self, col):
  return self.colLabels[col]

     def GetRowLabelValue(self, row):
  return row+1

     def IsEmptyCell(self, row, col):
  return False

     def GetValue(self, row, col):
  if col in range(0,4):
      return locale.format("%.*f",(4,self.data[row][col]),True)
  else:
      return self.data[row][col]

     def SetValue(self, row, col, value):
  pass

     def UpdateDataModel(self, newdata):
         # ... set new data ...
         self.GetView().BeginBatch()

  newNumRows = len(newdata)
  curNumRows = self.GetNumberRows()
  newNumCols = 6
  curNumCols = 6

  if newNumRows< curNumRows:
             msg = wx.grid.GridTableMessage(self,
                         wx.grid.GRIDTABLE_NOTIFY_ROWS_DELETED,
                         curNumRows - newNumRows, # position
                         curNumRows - newNumRows) # how many
             self.GetView().ProcessTableMessage(msg)
         if newNumRows> curNumRows:
             msg = wx.grid.GridTableMessage(self,
                         wx.grid.GRIDTABLE_NOTIFY_ROWS_APPENDED,
                         newNumRows - curNumRows) # how many
             self.GetView().ProcessTableMessage(msg)

         # ... same thing for columns ....

         self.GetView().EndBatch()

  self.data = newdata
         msg = wx.grid.GridTableMessage(self,
wx.grid.GRIDTABLE_REQUEST_VIEW_GET_VALUES)
         self.GetView().ProcessTableMessage(msg)

I do not know how I should use the SetValue() or the code I should put
when EVT_GRID_CELL_CHANGE is triggered to write back the data to the
database because:

1.- The data that is passed to the class above does not have a "ID
column" because the grid should not show that "ID column". I do not
know how I can do and update of a value.
2.- New rows can be inserted by the user. How do I know when I should
do an update of a value or a new insert in the datatable??

Thanks in advance