Mapped polymorphic class / multiple instance weirdness

3 views
Skip to first unread message

mog

unread,
Dec 29, 2009, 12:24:31 PM12/29/09
to sqlal...@googlegroups.com
Hi,

Hope you are well. I'm having a bit of trouble with something and would
love it if someone could please share some of their wisdom with me.

My program uses single table inheritance to store polymorphic objects,
one of which is a HttpTest. However, the spanner in the works seems to
be that I need my program to process HttpTest objects from two different
sources.

Most of the HttpTest objects will come from the database in ORM form via
SQLA; but then, some other HttpTest objects will be instantiated
manually from the program's configuration file parser.

The end result is that all the HttpTest objects get added to a
'hosttests' dictionary, which some code uses to iterate over and process
them. The processing basically consists of checking some of the HttpTest
attributes and then, if necessary, adding them into an event scheduler.

The problem I seem to be having, is that when the processing code
encounters a HttpTest object that was not created by SQLA (and it tries
to access its attributes), I get the following error:

File
"/usr/local/lib/python2.6/site-packages/SQLAlchemy-0.5.5-py2.6.egg/sqlalchemy/orm/attributes.py",
line 158, in __get__
return self.impl.get(instance_state(instance), instance_dict(instance))
AttributeError: 'HttpTest' object has no attribute '_sa_instance_state'

I'm not exactly sure what is going on here, but it seems like SQLA is
trying to lookup my "config generated" HttpTest object, and fails
because SQLA (quite understandable) has no record of it. Does this make
sense to anyone?

Any help or advice would be greatly appreciated. Thank you in advance
for your time and consideration.

Kind regards,
moggie

Chris Withers

unread,
Dec 29, 2009, 12:58:56 PM12/29/09
to sqlal...@googlegroups.com
mog wrote:
> The problem I seem to be having, is that when the processing code
> encounters a HttpTest object that was not created by SQLA (and it tries
> to access its attributes), I get the following error:
>
> File
> "/usr/local/lib/python2.6/site-packages/SQLAlchemy-0.5.5-py2.6.egg/sqlalchemy/orm/attributes.py",
> line 158, in __get__
> return self.impl.get(instance_state(instance), instance_dict(instance))
> AttributeError: 'HttpTest' object has no attribute '_sa_instance_state'

How are you instantiating these HttpTest objects?
(the ones that come from config, not SQLAlchemy?)

If you don't want breakage like this you have two options:

1. when you load the HttpTest objects from config, do so as if you were
goign to store them in the RDB via SA. Just make sure you never commit
the session where they're added.

2. Implement a separate class that has the same interface that you
require for non-SA HttpTests. You'll then have to figure out a way to
merge the lists of tests that come from config with the one that comes
from SA. That might be tricky depending on your requirements.

good luck,

Chris

mog

unread,
Dec 30, 2009, 7:13:24 AM12/30/09
to sqlal...@googlegroups.com, Chris Withers
On 29/12/2009 17:58, Chris Withers wrote:
> mog wrote:
>
>> The problem I seem to be having, is that when the processing code
>> encounters a HttpTest object that was not created by SQLA (and it tries
>> to access its attributes), I get the following error:
>>
>> File
>> "/usr/local/lib/python2.6/site-packages/SQLAlchemy-0.5.5-py2.6.egg/sqlalchemy/orm/attributes.py",
>> line 158, in __get__
>> return self.impl.get(instance_state(instance), instance_dict(instance))
>> AttributeError: 'HttpTest' object has no attribute '_sa_instance_state'
>>


Hi Chris,

Thanks for your help, it is greatly appreciated.


> How are you instantiating these HttpTest objects?
> (the ones that come from config, not SQLAlchemy?)
>

Basically just by importing the object from the model and instantiating
the config ones like any other class. Something like so:

from model.entities import HttpTest
test_list.append(HttpTest(blah, blah, blah, blah))


> If you don't want breakage like this you have two options:
>
> 1. when you load the HttpTest objects from config, do so as if you were
> goign to store them in the RDB via SA. Just make sure you never commit
> the session where they're added.
>
> 2. Implement a separate class that has the same interface that you
> require for non-SA HttpTests. You'll then have to figure out a way to
> merge the lists of tests that come from config with the one that comes
> from SA. That might be tricky depending on your requirements.
>

I think 2 is the most sensible thing to do at the moment. Means I now
have to maintain two copies of the same class, which is rather annoying,
but at least it's working now. I was wondering.. I don't suppose I could
get away with importing the new class as a different name could I? For
example...

from model.entities import HttpTest as HostTest
test_list.append(HttpTest(blah, blah, blah, blah))

Do you think that would help to convince SQLA that they should be
treated as different classes, so it wont go trying to look for mapping
relationships on the 'HostTest' ones?


> good luck,
>

hehe, thanks :)

Kind regards,
moggie

mog

unread,
Dec 30, 2009, 7:45:48 AM12/30/09
to sqlal...@googlegroups.com

Guess not... It's still the same class isn't it :(

Chris Withers

unread,
Jan 1, 2010, 5:14:28 PM1/1/10
to sqlal...@googlegroups.com
mog wrote:
> from model.entities import HttpTest as HostTest
> test_list.append(HttpTest(blah, blah, blah, blah))
>
> Do you think that would help to convince SQLA that they should be
> treated as different classes, so it wont go trying to look for mapping
> relationships on the 'HostTest' ones?

No.

Chris

--
Simplistix - Content Management, Batch Processing & Python Consulting
- http://www.simplistix.co.uk

Michael Bayer

unread,
Jan 1, 2010, 9:01:38 PM1/1/10
to sqlal...@googlegroups.com

On Dec 29, 2009, at 12:24 PM, mog wrote:

> The problem I seem to be having, is that when the processing code
> encounters a HttpTest object that was not created by SQLA (and it tries
> to access its attributes), I get the following error:
>
> File
> "/usr/local/lib/python2.6/site-packages/SQLAlchemy-0.5.5-py2.6.egg/sqlalchemy/orm/attributes.py",
> line 158, in __get__
> return self.impl.get(instance_state(instance), instance_dict(instance))
> AttributeError: 'HttpTest' object has no attribute '_sa_instance_state'

this seems like you aren't setting up your mappings soon enough. Make sure mapper() has been called for all classes (or, much easier, just use declarative to define the classes, works with separate Table objects too if you prefer via __table__) before you instantiate any HttpTest objects. The above symptom is due to an HttpTest object already existing before class instrumentation has been configured. If you never put those HttpTest objects in a Session, persistence will not be an issue.

>
> from model.entities import HttpTest as HostTest
> test_list.append(HttpTest(blah, blah, blah, blah))
>
> Do you think that would help to convince SQLA that they should be
> treated as different classes, so it wont go trying to look for mapping
> relationships on the 'HostTest' ones?

the __name__ attribute of "HostTest" above is still "HttpTest". The local name you're giving it isn't available to the runtime environment.

Reply all
Reply to author
Forward
0 new messages