Matthew Wilson | 2 Nov 00:25
Gravatar

Run SQLObject with a mock database connection?

I've got a lot of complex logic in some of my SQLObject methods, and I'd
like to verify that they work in unit tests, and I don't want to have
any kind of database connection, not even a SQLite in-memory database.

For example, I've got a parent-child relationship inside of one table,
where rows have an optional "parent row" field.  I want to set the
status on the parent row based on the status of all the different
children.

For example:

When all the children have a status AAA, I'll set the parent status to
AAA.  

When all the children have a status BBB, I'll set the parent
status to BBB.

When the children have different status, I'll set the parent status to
'Mixed'.

Of course, this is a simplification of something much uglier.

I want to make sure I execute the correct logic by feeding in lots of
possible scenarios through my function.

The test will run much faster if I can fake the connection to a
database.

Is this possible?  Any advice on mocking or stubbing a database
connection is welcome.
(Continue reading)

Dan Pascu | 3 Nov 13:07
Favicon
Gravatar

unicode fix


I just committed a fix in handling unicode values. The StringCol had an 
asymmetric behavior. When it read values from the database, it would use 
the database encoding to get a string if the db drivers returned an 
unicode value. However when an unicode value was given from python it 
would use a hardcoded ascii codec to get the value to write in the 
database. This asymmetry was weird and I have no idea why it was like 
this in the first place. It makes sense to use the database encoding for 
a value that will be written to the database in a column with that 
encoding. As a side note, the UnicodeCol uses the defined dbEncoding for 
both in and out of database operations.

I believe that this was the reason why so many people reported problems 
when using StringCol and they had unicode values on input with non-ascii 
content. The suggestion was to use UnicodeCol instead, but that is no 
longer necessary with this fix applied, as a StringCol will work just 
fine with unicode input as long as it can be encoded in the database 
encoding.

As it is now, the only difference between StringCol and UnicodeCol is that 
the later will allow one to define the db encoding per column, while the 
former will use a database/table wide encoding and one will return 
strings while the other unicode objects. But overall there should be more 
symmetry and consistency in how they are handled.

--

-- 
Dan

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
(Continue reading)

Oleg Broytmann | 4 Nov 19:37
X-Face
Picon
Favicon

Re: Run SQLObject with a mock database connection?

Hello! Sorry for late answer - I was out of town. (It's strange nobody else
answered the question.)

On Sat, Nov 01, 2008 at 11:25:07PM +0000, Matthew Wilson wrote:
> I've got a lot of complex logic in some of my SQLObject methods, and I'd
> like to verify that they work in unit tests, and I don't want to have
> any kind of database connection, not even a SQLite in-memory database.
[skip]
> The test will run much faster if I can fake the connection to a
> database.
> 
> Is this possible?  Any advice on mocking or stubbing a database
> connection is welcome.

   There is no read-made fake connection in SQLObject, and it'd be a bit
hard to write one, but writing one is the only option if you don't want to
use even SQLite.
   You have to implement a connection class - look at SQLiteConnection for
an example (sqlobject/sqlite/sqliteconnection.py). Oh, even better - look
at MySQLConnection and PostgresConnection - they don't have as many
internal helper methods. You don't need to implement metainformation
manipulation and retrieval methods - tableExists, add/delColumn,
columnsFromSchema, guessClass - but other methods are must.

Oleg.
--

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

-------------------------------------------------------------------------
(Continue reading)

Oleg Broytmann | 4 Nov 19:38
X-Face
Picon
Favicon

Re: unicode fix

On Mon, Nov 03, 2008 at 02:07:51PM +0200, Dan Pascu wrote:
> I just committed a fix in handling unicode values.

   Thank you!

Oleg.
--

-- 
     Oleg Broytmann            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 Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
Brian Long | 7 Nov 21:04
Picon
Gravatar

Cascade, MySQL, InnoDB

I'll admit I'm a newbie to SQLObject.  I understand MySQL only
supports cascade on delete using the InnoDB engine.  When I define a
class foreign key and specify "cascade=True", MySQL does not store
this because the default engine is MyISAM.

Since the sqlmeta createSQL code gets run after table creation,
specifying "ALTER TABLE foo ENGINE InnoDB" runs after the foreign key
constraint was created.  This means I have to re-construct / re-add
the constraint inside createSQL.  Are there any better ways to
accomplish this?

The SQLObject docs state:  "MySQL only supports transactions when
using the InnoDB backend, and SQLObject currently does not have
support for explicitly defining the backend when using createTable."
Are there any plans to change this in an upcoming release?  If I could
specify InnoDB for all created tables, the "cascade=True" attribute
would not get discarded by MySQL.

Thanks.

/Brian/

-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
Oleg Broytmann | 7 Nov 21:47
X-Face
Picon
Favicon

Re: Table parameters (Cascade, MySQL, InnoDB)

On Fri, Nov 07, 2008 at 03:04:03PM -0500, Brian Long wrote:
> Since the sqlmeta createSQL code gets run after table creation,
> specifying "ALTER TABLE foo ENGINE InnoDB" runs after the foreign key
> constraint was created.  This means I have to re-construct / re-add
> the constraint inside createSQL.  Are there any better ways to
> accomplish this?

   There is no, currently. IWBN for SQLObject to grow a concept of table
parameters. PostgreSQL, e.g., has a number of table parameters, like this:

CREATE TABLE cinemas (
   id serial,
   name text,
) INHERITS (parent_table) TABLESPACE diskvol1;

> Are there any plans to change this in an upcoming release?

   No, nobody has sent a patch. Do you want to be the champion?

Oleg.
--

-- 
     Oleg Broytmann            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 Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
(Continue reading)

Oleg Broytmann | 7 Nov 22:01
X-Face
Picon
Favicon

Re: Table parameters

On Fri, Nov 07, 2008 at 11:47:40PM +0300, Oleg Broytmann wrote:
>    IWBN for SQLObject to grow a concept of table
> parameters.

   Now when I thought about it for a few minutes I see both the API and the
implementation would be very simple:

class MyTable(SQLObject):
   class sqlmeta:
      tableParamSQL = 'ENGINE InnoDB'

   To implement this the only small change is to be in createTableSQL()
method in dbconnection.py.

   The bigger problem is to change the docs. :)

Oleg.
--

-- 
     Oleg Broytmann            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 Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
David Turner | 7 Nov 21:46
Favicon
Gravatar

Re: Cascade, MySQL, InnoDB

I think it will work to add the following to mysql/mysqlconnection.py:

    def createTableSQL(self, soClass):
        constraints = self.createReferenceConstraints(soClass)
        extraSQL = self.createSQL(soClass)
        createSql = ('CREATE TABLE %s (\n%s\n) engine=innodb' %
                (soClass.sqlmeta.table, self.createColumns(soClass)))
        return createSql, constraints + extraSQL

It might make sense to do this globally, on the theory that it's what
most people ought to want.  Else it appears that it would be easy to
make it an option per-connection.  I don't know about per-table.

On Fri, 2008-11-07 at 15:04 -0500, Brian Long wrote:
> I'll admit I'm a newbie to SQLObject.  I understand MySQL only
> supports cascade on delete using the InnoDB engine.  When I define a
> class foreign key and specify "cascade=True", MySQL does not store
> this because the default engine is MyISAM.
> 
> Since the sqlmeta createSQL code gets run after table creation,
> specifying "ALTER TABLE foo ENGINE InnoDB" runs after the foreign key
> constraint was created.  This means I have to re-construct / re-add
> the constraint inside createSQL.  Are there any better ways to
> accomplish this?
> 
> The SQLObject docs state:  "MySQL only supports transactions when
> using the InnoDB backend, and SQLObject currently does not have
> support for explicitly defining the backend when using createTable."
> Are there any plans to change this in an upcoming release?  If I could
> specify InnoDB for all created tables, the "cascade=True" attribute
(Continue reading)

Oleg Broytmann | 7 Nov 22:14
X-Face
Picon
Favicon

Re: Table parameters

On Sat, Nov 08, 2008 at 12:01:07AM +0300, Oleg Broytmann wrote:
> class MyTable(SQLObject):
>    class sqlmeta:
>       tableParamSQL = 'ENGINE InnoDB'

   Or adapting the idea from createSQL:

class MyTable(SQLObject):
   class sqlmeta:
      tableParamSQL = {'mysql': 'ENGINE InnoDB'}

Oleg.
--

-- 
     Oleg Broytmann            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 Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
Brian Long | 7 Nov 22:20
Picon
Gravatar

Re: Cascade, MySQL, InnoDB

After reading more MySQL docs, I found I could run the following:

connection.query("SET storage_engine = InnoDB")

I run this before running .createTable on my SQLObject classes and it
works well.

Thanks for the responses.

/Brian/

On Fri, Nov 7, 2008 at 3:46 PM, David Turner <novalis <at> openplans.org> wrote:
> I think it will work to add the following to mysql/mysqlconnection.py:
>
>    def createTableSQL(self, soClass):
>        constraints = self.createReferenceConstraints(soClass)
>        extraSQL = self.createSQL(soClass)
>        createSql = ('CREATE TABLE %s (\n%s\n) engine=innodb' %
>                (soClass.sqlmeta.table, self.createColumns(soClass)))
>        return createSql, constraints + extraSQL
>
> It might make sense to do this globally, on the theory that it's what
> most people ought to want.  Else it appears that it would be easy to
> make it an option per-connection.  I don't know about per-table.
>
> On Fri, 2008-11-07 at 15:04 -0500, Brian Long wrote:
>> I'll admit I'm a newbie to SQLObject.  I understand MySQL only
>> supports cascade on delete using the InnoDB engine.  When I define a
>> class foreign key and specify "cascade=True", MySQL does not store
>> this because the default engine is MyISAM.
(Continue reading)


Gmane