Hello,
many thanks for looking into this!
Am Dienstag, 23. September 2008 01:11:50 schrieb Ed Leafe:
> As Paul mentioned, you need to set biz.AutoPopulatePK to False for
> Dabo to send PK values back to the server. But that should cause Dabo
> to send the full record, including the PK to the backend server.
>
> If you have the time to do some debugging, can you replace the
> __saverow() method of dCursorMixin with the version below, that
> includes some debug output? Run your app using scenario 4 in your
> original email, and when you try to save the record, there should be a
> couple of lines of debug output. Copy that output and paste it into a
> reply email. This may not give us the answer, but it will help point
> us in the right direction.
>
>
> dCursorMixin.py, starting around line 1166:
>
> def __saverow(self, row):
> rec = self._records[row]
> recKey = self.pkExpression(rec)
> newrec = self._newRecords.has_key(recKey)
> newPKVal = None
> if newrec and self.AutoPopulatePK:
> # Some backends do not provide a means to retrieve
> # auto-generated PKs; for those, we need to create the
> # PK before inserting the record so that we can pass it
> on
> # to any linked child records. NOTE: if you are using
> # compound PKs, this cannot be done.
> newPKVal = self.pregenPK()
> if newPKVal and not self._compoundKey:
> self.setFieldVal(self.KeyField, newPKVal, row)
>
> print "newrec = ", newrec
> if newrec:
> diff = self._getNewRecordDiff(row)
> else:
> diff = self.getRecordStatus(row)
> print "diff = ", diff
> aq = self.AutoQuoteNames
> if diff:
>
>
Done.
Application started from a terminal. Starting it from the Dabo Editor may have
hidden error messages
1. Bizobj now looks like this, SQLite database unchanged:
class BizNum(dabo.biz.dBizobj):
def initProperties(self):
self.DataSource = "numtest"
self.KeyField = "idn"
self.AutoPopulatePK = False
self.SaveNewUnchanged = True
self.UserSQL = """SELECT idn, amount, remark FROM numtest"""
self.DefaultValues = {"idn": "ZZZ", "remark": None}
self.DataStructure = (("idn", "C", True, "numtest", "idn"),
("amount", "N", False, "numtest", "amount"),
("remark", "C", False, "numtest", "remark"))
Application started, new record entered (with manually changed PK),
button "save" pressed. Status line doesn't say anything about saved records,
only "Record 12/12 (EOF)" - this is one more than the table had before. Debug
output and traceback in the terminal:
newrec = False
diff = {'idn': (u'ZZZ', u'AC1'), 'amount': (Decimal("0.00"),
Decimal("75.60"))}
Traceback (most recent call last):
File
"/usr/lib/python2.5/site-packages/Dabo-0.8.4-py2.5.egg/dabo/ui/uiwx/dControlMixin.py",
line 27, in _onWxHit
self.raiseEvent(dEvents.Hit, evt, *args, **kwargs)
File
"/usr/lib/python2.5/site-packages/Dabo-0.8.4-py2.5.egg/dabo/ui/uiwx/dPemMixin.py",
line 928, in raiseEvent
super(dPemMixin, self).raiseEvent(eventClass, nativeEvent, *args,
**kwargs)
File
"/usr/lib/python2.5/site-packages/Dabo-0.8.4-py2.5.egg/dabo/lib/eventMixin.py",
line 92, in raiseEvent
bindingFunction(event)
File
"/usr/lib/python2.5/site-packages/Dabo-0.8.4-py2.5.egg/dabo/ui/uiwx/dForm.py",
line 682, in onSave
def onSave(self, evt): self.save()
File
"/usr/lib/python2.5/site-packages/Dabo-0.8.4-py2.5.egg/dabo/ui/uiwx/dForm.py",
line 355, in save
bizobj.saveAll()
File
"/usr/lib/python2.5/site-packages/Dabo-0.8.4-py2.5.egg/dabo/biz/dBizobj.py",
line 337, in saveAll
startTransaction=False)
File
"/usr/lib/python2.5/site-packages/Dabo-0.8.4-py2.5.egg/dabo/biz/dBizobj.py",
line 714, in scanChangedRows
self._moveToRowNum(row)
File
"/usr/lib/python2.5/site-packages/Dabo-0.8.4-py2.5.egg/dabo/biz/dBizobj.py",
line 986, in _moveToRowNum
self._CurrentCursor.moveToRowNum(rownum)
File
"/usr/lib/python2.5/site-packages/Dabo-0.8.4-py2.5.egg/dabo/db/dCursorMixin.py",
line 1589, in moveToRowNum
raise dException.dException, _("Invalid row specified.")
dabo.dException.dException: Invalid row specified.
2. No change in the application, new record entered and saved without changing
the default PK. Status line "Changes to all records saved", output in the
terminal:
newrec = True
diff = {'idn': (None, u'ZZZ'), 'amount': (None, Decimal("56.77")), 'remark':
(None, None)}
Looking into the database afterwards shows the new record. But there is still
one abnormality: an "after insert" trigger in the database inserts text into
the "remark" field, if it is NULL. If I save the new record and navigate away
from it and back in my application, this added remark isn't there, the entry
field still shows "<None>". But after closing the application and opening the
SQLite command line client I can see the remark in the new record.
Of course this works exactly once, because the default PK is a fixed string.
3. No default PK:
...
self.SaveNewUnchanged = False
...
self.DefaultValues = None
PK entered manually (unique value). Status line as before, no traceback, debug
output in the terminal:
newrec = False
diff = {'idn': (u'', u'AC1'), 'amount': (None, Decimal("65.44"))}
Navigating in the application shows the new record (without the remark the
insert trigger should add), looking into the table afterwards doesn't show
it. This is the outcome I like least.
4. self.SaveNewUnchanged = True, no other changes:
Output in the terminal:
newrec = False
diff = {'idn': (u'', u'AC2'), 'amount': (None, Decimal("345.6"))}
Traceback (most recent call last):
File
"/usr/lib/python2.5/site-packages/Dabo-0.8.4-py2.5.egg/dabo/ui/uiwx/dControlMixin.py",
line 27, in _onWxHit
self.raiseEvent(dEvents.Hit, evt, *args, **kwargs)
File
"/usr/lib/python2.5/site-packages/Dabo-0.8.4-py2.5.egg/dabo/ui/uiwx/dPemMixin.py",
line 928, in raiseEvent
super(dPemMixin, self).raiseEvent(eventClass, nativeEvent, *args,
**kwargs)
File
"/usr/lib/python2.5/site-packages/Dabo-0.8.4-py2.5.egg/dabo/lib/eventMixin.py",
line 92, in raiseEvent
bindingFunction(event)
File
"/usr/lib/python2.5/site-packages/Dabo-0.8.4-py2.5.egg/dabo/ui/uiwx/dForm.py",
line 682, in onSave
def onSave(self, evt): self.save()
File
"/usr/lib/python2.5/site-packages/Dabo-0.8.4-py2.5.egg/dabo/ui/uiwx/dForm.py",
line 355, in save
bizobj.saveAll()
File
"/usr/lib/python2.5/site-packages/Dabo-0.8.4-py2.5.egg/dabo/biz/dBizobj.py",
line 337, in saveAll
startTransaction=False)
File
"/usr/lib/python2.5/site-packages/Dabo-0.8.4-py2.5.egg/dabo/biz/dBizobj.py",
line 714, in scanChangedRows
self._moveToRowNum(row)
File
"/usr/lib/python2.5/site-packages/Dabo-0.8.4-py2.5.egg/dabo/biz/dBizobj.py",
line 986, in _moveToRowNum
self._CurrentCursor.moveToRowNum(rownum)
File
"/usr/lib/python2.5/site-packages/Dabo-0.8.4-py2.5.egg/dabo/db/dCursorMixin.py",
line 1589, in moveToRowNum
raise dException.dException, _("Invalid row specified.")
dabo.dException.dException: Invalid row specified.
To me this begins to look as if the primary key cannot be changed manually
away from a default value (which might be calculated by an appropriate
function, as in Pauls example). It seems quite probable that it's not often
possible or useful to assign primary keys in this way, but it can be: small
and very slowly growing table, the PKs are mnemonics (very helpful for ad-hoc
queries when used as foreign keys), and new records for this table are only
entered locally, no multi-user complications. To me an additional
autoincrement PK looks like overkill for this case.
I'm beginning to think this might not be a special Dabo problem. While my old
Delphi 6 application has no problems with manually created PKs, I suspect
ADO.NET or the QtSQL module might not like them either. Will experiment a
little more if I can find the time.
Thanks again,
Sibylle
--
Dr. Sibylle Koczian
_______________________________________________
Post Messages to: [email protected]
Subscription Maintenance: http://leafe.com/mailman/listinfo/dabo-users
Searchable Archives: http://leafe.com/archives/search/dabo-users
This message: http://leafe.com/archives/byMID/[EMAIL PROTECTED]