Thread: [SQLObject] Inheritance strangeness
SQLObject is a Python ORM.
Brought to you by:
ianbicking,
phd
|
From: <ab...@ne...> - 2005-06-03 09:06:05
|
I've discovered what seems to be a bug in sqlobject class inheritance.
An inherited class whose parent defines a foreign key, can only use that =
foreign
key/pointer if they themselves define a data attribute. If the inherited=
class
does not contribute a new data attribute, attempting to use the foreign k=
ey
(which is defined by the parent) will generate an attribute error.
P.S. You need to grab the latest source from the subversion repository in=
order
to get the InheritableSQLObject class. Release 0.6.1 doesn't come with it=
.
#----------------------------------------------
from sqlobject import *
from sqlobject.inheritance import InheritableSQLObject
from sqlobject.sqlite import builder; SQLiteConnection =3D builder()
conn =3D SQLiteConnection('persontest3.db', debug=3DFalse)
class Cubicle(SQLObject):
_connection =3D conn
location =3D StringCol()
occupiedby =3D ForeignKey('Person', default=3DNone) # and subclasses
class Person(InheritableSQLObject):
_connection =3D conn
cubicle =3D ForeignKey('Cubicle')
class Employee(Person):
_connection =3D conn
_inheritable =3D False # comment this line to sol=
ve bug OR
#position =3D StringCol(default=3D'Chief') # uncomment this line to=
solve bug
=20
# tests =20
Cubicle.dropTable(True)
Cubicle.createTable()
Person.dropTable(True)
Person.createTable()
Employee.dropTable(True)
Employee.createTable()
c =3D Cubicle(location=3D'first floor')
c.occupiedby =3D Employee(cubicle=3Dc)
# The following will crash with the error
# 'Employee' object has no attribute '_SO_val_cubicleID'
print 'c.occupiedby.cubicle', c.occupiedby.cubicle # BOOM!
#----------------------------------------------
Admittedly, most people using inherited classes want to define extra attr=
ibutes
- that's usually the whole point of an inherited class. So they would no=
t run
into this problem. However in my situation not all my inherited classes =
define
extra attributes (e.g. they instead have different behaviour etc.) so it =
is a
real problem for me.
-Andy Bulka
www.atug.com/andypatterns
------------------------------------------------------------
This email was sent from Netspace Webmail: http://www.netspace.net.au
|
|
From: Oleg B. <ph...@ph...> - 2005-06-03 09:20:13
|
On Fri, Jun 03, 2005 at 07:05:50PM +1000, ab...@ne... wrote:
> An inherited class whose parent defines a foreign key, can only use that foreign
> key/pointer if they themselves define a data attribute. If the inherited class
> does not contribute a new data attribute, attempting to use the foreign key
> (which is defined by the parent) will generate an attribute error.
I'll look into it.
> from sqlobject.sqlite import builder; SQLiteConnection = builder()
> conn = SQLiteConnection('persontest3.db', debug=False)
Oops! Why not just
conn = connectionForURI("sqlite:/persontest3.db?debug=")
or even
conn = "sqlite:/persontest3.db?debug="
???
Oleg.
--
Oleg Broytmann http://phd.pp.ru/ ph...@ph...
Programmers don't die, they just GOSUB without RETURN.
|
|
From: <ab...@ne...> - 2005-06-03 10:02:19
|
Quoting Oleg Broytmann <ph...@ph...>:
>=20
> > from sqlobject.sqlite import builder; SQLiteConnection =3D builder()
> > conn =3D SQLiteConnection('persontest3.db', debug=3DFalse)
>=20
> Oops! Why not just
> conn =3D connectionForURI("sqlite:/persontest3.db?debug=3D")
> or even
> conn =3D "sqlite:/persontest3.db?debug=3D"
> ???
Thanks - these simpler syntaxes work! I am converted!
I was forced to use the messy syntax because in the current official sqlo=
bject
documentation at http://www.sqlobject.org/docs/SQLObject.html I didn't ha=
ve much
luck. The recommended syntaxes mentioned there are:
conn =3D SQLiteConnection('database.db')
conn =3D 'sqlite://path/to/database.db'
Well, using the first works, but warns me that it is deprecated.
And the second syntax seemed to give me errors because of the double slas=
hes - I
was typing in=20
conn =3D "sqlite://persontest3.db?debug=3D" # FAILS
instead of
conn =3D "sqlite:/persontest3.db?debug=3D" # WORKS :-)
So I'm not sure if that's a typo in the documentation, or the // is meant=
to be
like a http address (but you can't use sqlite over http anyway?).
Furthermore, my understanding of connection strings is so bad that I can'=
t seem
to specify a windows path name to a sqlite file either e.g.=20
conn =3D 'sqlite:/"C:/person test/persontest3.db"'
conn =3D 'sqlite:/C:/person test/persontest3.db'
conn =3D 'sqlite:/C:\\person test\\persontest3.db'
conn =3D 'sqlite://C:\\person test\\persontest3.db'
etc.
all fail. I wonder if there is an url somewhere that describes this stuf=
f -
maybe it was adopted recently by sqlobject because it is a common standar=
d and
described somewhere?
-Andy Bulka
http://www.atug.com/andypatterns
------------------------------------------------------------
This email was sent from Netspace Webmail: http://www.netspace.net.au
|
|
From: Oleg B. <ph...@ma...> - 2005-06-03 10:23:00
|
On Fri, Jun 03, 2005 at 08:01:44PM +1000, ab...@ne... wrote:
> conn = "sqlite://persontest3.db?debug=" # FAILS
> instead of
> conn = "sqlite:/persontest3.db?debug=" # WORKS :-)
>
> So I'm not sure if that's a typo in the documentation, or the // is meant to be
> like a http address (but you can't use sqlite over http anyway?).
Not http, not even an URL. It is URI. Just a syntax that's paresed by
SQLObject, not any network engine.
> Furthermore, my understanding of connection strings is so bad that I can't seem
> to specify a windows path name to a sqlite file either e.g.
> conn = 'sqlite:/"C:/person test/persontest3.db"'
> conn = 'sqlite:/C:/person test/persontest3.db'
> conn = 'sqlite:/C:\\person test\\persontest3.db'
> conn = 'sqlite://C:\\person test\\persontest3.db'
> etc.
> all fail.
conn = 'sqlite://C|/person test/persontest3.db'
Oleg.
--
Oleg Broytmann http://phd.pp.ru/ ph...@ph...
Programmers don't die, they just GOSUB without RETURN.
|
|
From: Oleg B. <ph...@ma...> - 2005-06-03 10:34:45
|
On Fri, Jun 03, 2005 at 02:22:54PM +0400, Oleg Broytmann wrote:
> Not http, not even an URL. It is URI. Just a syntax that's paresed by
s/paresed/parsed/. Sorry.
Oleg.
--
Oleg Broytmann http://phd.pp.ru/ ph...@ph...
Programmers don't die, they just GOSUB without RETURN.
|
|
From: Brian B. <ex...@gm...> - 2005-06-05 06:00:03
|
Oleg Broytmann wrote: > On Fri, Jun 03, 2005 at 08:01:44PM +1000, ab...@ne... wrote: > >> conn = "sqlite://persontest3.db?debug=" # FAILS >>instead of >> conn = "sqlite:/persontest3.db?debug=" # WORKS :-) >> >>So I'm not sure if that's a typo in the documentation, or the // is meant to be >>like a http address (but you can't use sqlite over http anyway?). > > > Not http, not even an URL. It is URI. Just a syntax that's paresed by > SQLObject, not any network engine. Also, I'm pretty sure the connection syntax Andy used is the only way to specify a relative path. I also use that form when using SQLObject with Windows. -- Brian Beck Adventurer of the First Order |
|
From: <ab...@ne...> - 2005-06-06 05:02:19
|
Brian Beck wrote:
> Also, I"m pretty sure the connection syntax Andy used is the only way t=
o
> specify a relative path. I also use that form when using SQLObject with
> Windows.
Indeed that's right - the syntax I originally used
from sqlobject.sqlite import builder; SQLiteConnection =3D builder()
conn =3D SQLiteConnection('persontest3.db', debug=3DFalse)
whilst convoluted, at least lets me specify that the db be in the same di=
rectory
as my source code. So whilst the shorter syntax works - I've since disco=
vered
that it actually creates the db file in the root of my windows C: drive! =
Not
what I want.
conn =3D "sqlite:/persontest3.db?debug=3D"
Also, I'm still not clear as to why the documentation refers to a double =
slash
// but in actual use, only a single slash actually works. E.g. the code l=
ine
above works, but if you put in // it won't work.
Note that when specifying a full pathname, it seems that either double or=
single
path will work. e.g.
conn =3D "sqlite://C|/person test/persontest3.db" OR
conn =3D "sqlite:/C|/person test/persontest3.db"
In summary:
It seems that "sqlite://file" style connection strings=20
* only actually work if its a single slash
* don't let you put the db in the same directory or a relative direct=
ory
-Andy Bulka
http://www.atug.com/andypatterns
------------------------------------------------------------
This email was sent from Netspace Webmail: http://www.netspace.net.au
|
|
From: Oleg B. <ph...@ph...> - 2005-06-03 14:50:58
|
On Fri, Jun 03, 2005 at 07:05:50PM +1000, ab...@ne... wrote:
> class Employee(Person):
> _connection = conn
> _inheritable = False # comment this line to solve bug OR
> #position = StringCol(default='Chief') # uncomment this line to solve bug
I've found the cause of the problem. Inheritance machinery does not
like classes that don't have attributes (beside obvious id). The
machinery needs to propagate columns from an every parent class to all
its children, but in a class with no attributes the code is not
triggered!
I'll look further if I can trigger the code somewhere else. Meanwhile
you've found two ways to overcome the problem. Either add a fake column
or a StringCol("childName") via setting _inheritable = True.
> in my situation not all
> my inherited classes define extra attributes (e.g. they instead have
> different behaviour etc.)
PS. I wonder how do they have different behavior without any
attributes? Via properties, I suppose?
Oleg.
--
Oleg Broytmann http://phd.pp.ru/ ph...@ph...
Programmers don't die, they just GOSUB without RETURN.
|
|
From: michelts <mic...@gm...> - 2005-06-03 15:22:43
|
For now I use the following syntax:
Employee.select(Person.q.name =3D=3D 'some name')
The column name is originally from Person...
regards,
On 6/3/05, Oleg Broytmann <ph...@ph...> wrote:
> On Fri, Jun 03, 2005 at 07:05:50PM +1000, ab...@ne... wrote:
> > class Employee(Person):
> > _connection =3D conn
> > _inheritable =3D False # comment this line to s=
olve bug OR
> > #position =3D StringCol(default=3D'Chief') # uncomment this line =
to solve bug
>=20
> I've found the cause of the problem. Inheritance machinery does not
> like classes that don't have attributes (beside obvious id). The
> machinery needs to propagate columns from an every parent class to all
> its children, but in a class with no attributes the code is not
> triggered!
> I'll look further if I can trigger the code somewhere else. Meanwhile
> you've found two ways to overcome the problem. Either add a fake column
> or a StringCol("childName") via setting _inheritable =3D True.
>=20
> > in my situation not all
> > my inherited classes define extra attributes (e.g. they instead have
> > different behaviour etc.)
>=20
> PS. I wonder how do they have different behavior without any
> attributes? Via properties, I suppose?
>=20
> Oleg.
> --
> Oleg Broytmann http://phd.pp.ru/ ph...@ph...
> Programmers don't die, they just GOSUB without RETURN.
>=20
>=20
> -------------------------------------------------------
> This SF.Net email is sponsored by Yahoo.
> Introducing Yahoo! Search Developer Network - Create apps using Yahoo!
> Search APIs Find out how you can build Yahoo! directly into your own
> Applications - visit http://developer.yahoo.net/?fr=3Doffad-ysdn-ostg-q22=
005
> _______________________________________________
> sqlobject-discuss mailing list
> sql...@li...
> https://lists.sourceforge.net/lists/listinfo/sqlobject-discuss
>=20
--=20
Michel Thadeu Sabchuk
Curitiba - Brasil
|
|
From: Oleg B. <ph...@ph...> - 2005-06-03 16:15:41
|
On Fri, Jun 03, 2005 at 07:05:50PM +1000, ab...@ne... wrote:
> I've discovered what seems to be a bug in sqlobject class inheritance.
I have committed a patch at the revision 810 that should fix this
problem and also all problems with inherited tables with no attributes.
Please give it a try and report.
Oleg.
--
Oleg Broytmann http://phd.pp.ru/ ph...@ph...
Programmers don't die, they just GOSUB without RETURN.
|
|
From: <ab...@ne...> - 2005-06-06 02:31:55
|
Quoting Oleg Broytmann <ph...@ph...>: > On Fri, Jun 03, 2005 at 07:05:50PM +1000, ab...@ne... wrote: > > I've discovered what seems to be a bug in sqlobject class inheritance= . >=20 > I have committed a patch at the revision 810 that should fix this > problem and also all problems with inherited tables with no attributes. > Please give it a try and report. Seems to be fixed now - thanks very much! > > in my situation not all > > my inherited classes define extra attributes (e.g. they instead have > > different behaviour etc.) > =20 > PS. I wonder how do they have different behavior without any > attributes? Via properties, I suppose? The subclasses have different behaviour in that they all have a method ca= lled e.g. 'Do' but implement it differently. Some subclasses need extra attri= butes in order to support their particular imlpementation, other subclasses don= 't. I've actually implemented a reasonably complex 'state design pattern' and= the states are subclasses, which are all persisted via sqlobject. Thank good= ness sqlobject came with inheritance support - and I think such an elegant way= of doing it too. Andy Bulka http://www.atug.com/andypatterns ------------------------------------------------------------ This email was sent from Netspace Webmail: http://www.netspace.net.au |