Tom Coetser | 7 Dec 2009 17:41

InheritableSQLObject: Data corruption when child record create fails

Hi all,

I am doing some tests with InheritableSQLobject and have run into a problem 
which I hope to get some feedback on.

The problem is that when creating a new object based on an 
InheritableSQLObject class, and the creation of the child object fails after 
a new parent was created, the parent record will remain in the database 
without the relevant child.

Here is a short example:

~~~~~~~~~~ file: inheritTest3.py ~~~~~~~~~~~~
from sqlobject import *
from sqlobject.inheritance import InheritableSQLObject

__connection__ = "sqlite:/:memory:"

class Vehicle(InheritableSQLObject):
    vid = StringCol(notNone=True, default=None, unique=True)
    wheels = IntCol()

class Bicycle(Vehicle):
    seats = IntCol(notNone=True, default=None)

class Car(Vehicle):
    doors = IntCol(notNone=True, default=None)

def createTables():
    Vehicle.createTable()
(Continue reading)

Oleg Broytman | 7 Dec 2009 19:10
X-Face
Picon
Favicon

Re: InheritableSQLObject: Data corruption when child record create fails

Hi!

On Mon, Dec 07, 2009 at 06:41:54PM +0200, Tom Coetser wrote:
> The problem is that when creating a new object based on an 
> InheritableSQLObject class, and the creation of the child object fails after 
> a new parent was created, the parent record will remain in the database 
> without the relevant child.

   A valid concern, sure. I never stumbled upon the problem because I
always use transactions, and on any exception I just ABORT the transaction;
on ABORT the DB removes the half created parent.

> I'm attaching a patch as a possible fix for this

   Thank you!

> -        super(InheritableSQLObject, self)._create(id, **kw)
> +        # TC: Create this record and catch all exceptions in order to destroy
> +        # TC: the parent if the child can not be created.
> +        try:
> +            super(InheritableSQLObject, self)._create(id, **kw)
> +        except:
> +            # TC: If we are the child, destroy the parent
> +            if self.sqlmeta.parentClass:
> +                self._parent.destroySelf()
> +                self._parent = None
> +            # TC: Reraise the original exception
> +            raise
> +

(Continue reading)

Tom Coetser | 10 Dec 2009 22:18

Changing validator messages

Hi All,

I am using the field validator option to auto validate certain fields,
and return more meaningful error messages than the default ones returned
by formencode. It seems that there is a problem with changing some of
the messages though.

Given this sample file :

~~~~~~~~~~~~~ validatorTest.py ~~~~~~~~~~~~~~~~~~~~
from sqlobject import *
from formencode import validators, Invalid

__connection__ = "sqlite:/:memory:"

validName = validators.String(not_empty=True, min=5,
                     messages={'empty': 'The name may not be empty.',
                               'noneType': 'The name is None',
                               'tooShort': 'The name is too short',
                              }
                             )

class foo(SQLObject):
    name = StringCol(validator=validName)

foo.createTable()

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

When passing a value of None for 'name' when creating a new foo, this is
(Continue reading)

Oleg Broytman | 10 Dec 2009 22:56
X-Face
Picon
Favicon

Re: Changing validator messages

On Thu, Dec 10, 2009 at 11:18:33PM +0200, Tom Coetser wrote:
> >>> vt.foo(name=None)                                                 
>     raise Invalid(self.message('empty', state), value, state)
> formencode.api.Invalid: Please enter a value

   foo(name=None) raises

    raise Invalid(self.message('empty', state), value, state)
formencode.api.Invalid: The name may not be empty.

   for me. I suspect you are using old buggy version of FormEncode.

Oleg.
--

-- 
     Oleg Broytman            http://phd.pp.ru/            phd <at> phd.pp.ru
           Programmers don't die, they just GOSUB without RETURN.

------------------------------------------------------------------------------
Return on Information:
Google Enterprise Search pays you back
Get the facts.
http://p.sf.net/sfu/google-dev2dev
Tom Coetser | 11 Dec 2009 07:54

Re: Changing validator messages

On Thursday 10 December 2009 23:56:51 Oleg Broytman wrote:
> On Thu, Dec 10, 2009 at 11:18:33PM +0200, Tom Coetser wrote:
> > >>> vt.foo(name=None)
> >
> >     raise Invalid(self.message('empty', state), value, state)
> > formencode.api.Invalid: Please enter a value
>
>    foo(name=None) raises
>
>     raise Invalid(self.message('empty', state), value, state)
> formencode.api.Invalid: The name may not be empty.
>
>    for me. I suspect you are using old buggy version of FormEncode.

And your suspicion was correct :-) The stable version in Debian Lenny seems to 
be formencode 1.0.1, but updating to 1.2 seems to have fixed the problem.

Thanks very much.

Cheers,
 Tom

------------------------------------------------------------------------------
Return on Information:
Google Enterprise Search pays you back
Get the facts.
http://p.sf.net/sfu/google-dev2dev
Oleg Broytman | 11 Dec 2009 10:49
X-Face
Picon
Favicon

Re: Changing validator messages

On Fri, Dec 11, 2009 at 08:54:16AM +0200, Tom Coetser wrote:
> And your suspicion was correct :-) The stable version in Debian Lenny seems to 
> be formencode 1.0.1, but updating to 1.2 seems to have fixed the problem.

   SQLObject's setup.py list requirement "FormEncode>=1.1.1", and I think
the bugfix I made between 1.1.0 and 1.1.1 is related to the problem. If you
ran setup.py install it should upgrade FormEncode automatically, shouldn't
it?
   I use Debian too, but I have to install a lot of software manually,
especially Python modules. Debian "stable" is too stable (and I don't have
time to upgrade to "testing" now).

Oleg.
--

-- 
     Oleg Broytman            http://phd.pp.ru/            phd <at> phd.pp.ru
           Programmers don't die, they just GOSUB without RETURN.

------------------------------------------------------------------------------
Return on Information:
Google Enterprise Search pays you back
Get the facts.
http://p.sf.net/sfu/google-dev2dev
Petr Jakeš | 18 Dec 2009 01:19
Picon

bug report: limit(num) method for Firebird

Hi,
I am trying to use the limit(num) method.
http://www.sqlobject.org/SelectResults.html

For the SQLite everything works as expected.

For the Firebird database I am getting following error:

Traceback (most recent call last):
  File "testSqlObject.py", line 55, in <module>
    for r in os:
  File "/usr/lib/python2.5/site-packages/SQLObject-0.10.1-py2.5.egg/sqlobject/sresults.py", line 179, in __iter__
    return iter(list(self.lazyIter()))
  File "/usr/lib/python2.5/site-packages/SQLObject-0.10.1-py2.5.egg/sqlobject/sresults.py", line 187, in lazyIter
    return conn.iterSelect(self)
  File "/usr/lib/python2.5/site-packages/SQLObject-0.10.1-py2.5.egg/sqlobject/dbconnection.py", line 395, in iterSelect
    select, keepConnection=False)
  File "/usr/lib/python2.5/site-packages/SQLObject-0.10.1-py2.5.egg/sqlobject/dbconnection.py", line 631, in __init__
    self.query = self.dbconn.queryForSelect(select)
  File "/usr/lib/python2.5/site-packages/SQLObject-0.10.1-py2.5.egg/sqlobject/dbconnection.py", line 409, in queryForSelect
    return self.sqlrepr(select.queryForSelect())
  File "/usr/lib/python2.5/site-packages/SQLObject-0.10.1-py2.5.egg/sqlobject/dbconnection.py", line 591, in sqlrepr
    return sqlrepr(v, self.dbName)
  File "/usr/lib/python2.5/site-packages/SQLObject-0.10.1-py2.5.egg/sqlobject/converters.py", line 211, in sqlrepr
    return reprFunc(db)
  File "/usr/lib/python2.5/site-packages/SQLObject-0.10.1-py2.5.egg/sqlobject/sqlbuilder.py", line 677, in __sqlrepr__
    select = dbConnectionForScheme(db)._queryAddLimitOffset(select, start, end)
  File "/usr/lib/python2.5/site-packages/SQLObject-0.10.1-py2.5.egg/sqlobject/firebird/firebirdconnection.py", line 120, in _queryAddLimitOffset
    match = cls.limit_re.match(query)
AttributeError: class FirebirdConnection has no attribute 'limit_re'



Adding the line :
cls.limit_re = re.compile('^\s*(select )(.*)', re.IGNORECASE)
before the line:
match = cls.limit_re.match(query)

in the method _queryAddLimitOffset before in the file firebirdconnection.py solves the problem.

I am not a Python guru and I am sure this is not a "high-level" solution.
Oleg surely knows how to patch it properly :D

Regards

Petr


------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev 
_______________________________________________
sqlobject-discuss mailing list
sqlobject-discuss <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sqlobject-discuss
Oleg Broytman | 18 Dec 2009 10:34
X-Face
Picon
Favicon

Re: bug report: limit(num) method for Firebird

On Fri, Dec 18, 2009 at 01:19:25AM +0100, Petr Jake?? wrote:
>   File
> "/usr/lib/python2.5/site-packages/SQLObject-0.10.1-py2.5.egg/sqlobject/firebird/firebirdconnection.py",
> line 120, in _queryAddLimitOffset
>     match = cls.limit_re.match(query)
> AttributeError: class FirebirdConnection has no attribute 'limit_re'

   I'll look at it.

Oleg.
--

-- 
     Oleg Broytman            http://phd.pp.ru/            phd <at> phd.pp.ru
           Programmers don't die, they just GOSUB without RETURN.

------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev 
Oleg Broytman | 20 Dec 2009 16:41
X-Face
Picon
Favicon

Re: bug report: limit(num) method for Firebird

Hi!

On Fri, Dec 18, 2009 at 01:19:25AM +0100, Petr Jake?? wrote:
>   File
> "/usr/lib/python2.5/site-packages/SQLObject-0.10.1-py2.5.egg/sqlobject/firebird/firebirdconnection.py",
> line 120, in _queryAddLimitOffset
>     match = cls.limit_re.match(query)
> AttributeError: class FirebirdConnection has no attribute 'limit_re'

   This is the patch that I think fixes the problem:

Index: firebirdconnection.py
===================================================================
--- firebirdconnection.py       (revision 4047)
+++ firebirdconnection.py       (working copy)
 <at>  <at>  -10,6 +10,8  <at>  <at> 
     dbName = 'firebird'
     schemes = [dbName]

+    limit_re = re.compile('^\s*(select )(.*)', re.IGNORECASE)
+
     def __init__(self, host, db, user='sysdba',
                  password='masterkey', autoCommit=1,
                  dialect=None, role=None, charset=None, **kw):
 <at>  <at>  -18,8 +20,6  <at>  <at> 
             import kinterbasdb
         self.module = kinterbasdb

-        self.limit_re = re.compile('^\s*(select )(.*)', re.IGNORECASE)
-
         self.host = host
         self.db = db
         self.user = user

Oleg.
--

-- 
     Oleg Broytman            http://phd.pp.ru/            phd <at> phd.pp.ru
           Programmers don't die, they just GOSUB without RETURN.

------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev 
David | 31 Dec 2009 17:56
Picon

Adding support for additional database

I would like to add support to SQLObject for the www.rdbhost.com service.

Rdbhost provides Postgresql databases via web-service.   We have a DB
API 2 interface module, called 'Rdbhdb', to facilitate using our
hosted databases from Python, and I would like to provide 'drop-in'
support for SQLObject.

In that pursuit, I have a suggestion and a question or two:

It seems that the scheme from an opener URI is used to select the
driver, but is not provided to that driver's constructor.  For
example, the 'Pygresql' scheme will instantiate a
'pgconnection::PostgresConnection', but the __init__ is not provided
the scheme name; a Pygresql user would have to provide an explicit
backend parameter to identify the Pygresql api module.  I suggest that
dbconnection.py be modified to pass a 'scheme' parameter to the
constructors, where it would appear as part of the **kw param.

In the pgconnection init, the self.use_dsn parameter is set, and then
the self.dsn_dict and self.dsn are both created.  Why are those two
built, when a dsn string is already available?  The makeConnection
method uses only the self.dsn or only the self.dsn_dict, depending on
self.use_dsn.

What is the preferred tool for patch-making under WinXP?

Are there preconditions for adding a new database to SQLObject?

Thank you,
David

--

-- 
dkeeney <at> travelbyroad.net
Rdbhost -> SQL databases as a webservice [www.rdbhost.com]

------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev 

Gmane