relationship trouble

17 views
Skip to first unread message

Jakob L.

unread,
Oct 26, 2011, 12:10:40 PM10/26/11
to sqlal...@googlegroups.com
Hi!

I added a new self-referential relationship to one of my tables but since I couldn't find how to create the new column through SA I added it to the db manually after checking how it's been done before. 

The code looks like this (using elixir):
class User(Entity):
    username = Field(String(80),  primary_key=True)

    # New fields
    parent = ManyToOne('User')
    children = OneToMany('User')

So I added a field in the db with the name "parent_name" since I noticed thats how SA names foreign keys and I also indexed it with the name ix_user_parent_name

Do I need to do anything else to get this to work or have I done anything wrong? 

What I get is: " 'str' object has no attribute '_state' " for that object in _get_committed_attr_by_column. 

I read that this means that I add a string to a relationship object, but I could access the parents fields when testing. 





Jakob L.

unread,
Oct 26, 2011, 12:14:47 PM10/26/11
to sqlal...@googlegroups.com
Sorry, I named the new field "parent_username" and the index " ix_user_parent_username"

Michael Bayer

unread,
Oct 26, 2011, 12:50:49 PM10/26/11
to sqlal...@googlegroups.com

On Oct 26, 2011, at 12:10 PM, Jakob L. wrote:

> Hi!
>
> I added a new self-referential relationship to one of my tables but since I couldn't find how to create the new column through SA I added it to the db manually after checking how it's been done before.
>
> The code looks like this (using elixir):
> class User(Entity):
> username = Field(String(80), primary_key=True)
>
> # New fields
> parent = ManyToOne('User')
> children = OneToMany('User')
>
> So I added a field in the db with the name "parent_name" since I noticed thats how SA names foreign keys

OK you're getting confused here due to Elixir. SQLAlchemy doesn't ever name a foreign key anything - that would be what Elixir is doing.

> and I also indexed it with the name ix_user_parent_name
>
> Do I need to do anything else to get this to work or have I done anything wrong?

Seems fine assuming that naming convention you're using is correct (I haven't used Elixir much).

>
> What I get is: " 'str' object has no attribute '_state' " for that object in _get_committed_attr_by_column.

So this is something occurring on usage, not on the mapping, which is not shown here. Somewhere a string value is being passed where an object should be, such as if you were to say User().parent = "some string". I know that's not explicitly what you're doing here but we can't know the issue without full code and a stack trace.

> I read that this means that I add a string to a relationship object, but I could access the parents fields when testing.

It is likely more subtle where a string is being misinterpreted. The offending line of code at least + full stack trace is the most important.

Jakob Levonian

unread,
Oct 27, 2011, 4:01:00 AM10/27/11
to sqlal...@googlegroups.com

On Oct 26, 2011, at 6:50 PM, Michael Bayer wrote:

>
> OK you're getting confused here

If I had a nickel =P

>
> So this is something occurring on usage, not on the mapping, which is not shown here. Somewhere a string value is being passed where an object should be, such as if you were to say User().parent = "some string". I know that's not explicitly what you're doing here but we can't know the issue without full code and a stack trace.
>

Basically what I'm doing is adding an authed user to the framework.

Traceback (most recent call last):
File "/usr/sbin/admin-web", line 25, in service
Application.service(self)
File "/usr/lib/python2.5/site-packages/smisk/mvc/__init__.py", line 879, in service
rsp = self._call_leaf_and_handle_model_session(req_args, req_params)
File "/usr/lib/python2.5/site-packages/smisk/mvc/__init__.py", line 706, in _call_leaf_and_handle_model_session
rsp = self._call_leaf(req_args, req_params)
File "/usr/lib/python2.5/site-packages/smisk/mvc/__init__.py", line 695, in _call_leaf
return self._leaf_filter(*args, **params)
File "/usr/lib/python2.5/site-packages/smisk/mvc/decorators.py", line 72, in f
return filter(leaf, *va, **kw)
File "/var/mysite/lib/mysite/admin_web/__init__.py", line 50, in add_authorized_user_to_rsp
return leaf(*va, **kw)
File "/usr/lib/python2.5/site-packages/smisk/mvc/__init__.py", line 298, in <lambda>
self._leaf_filter = lambda *va, **kw: filter(self.destination)(*va, **kw)
File "/usr/lib/python2.5/site-packages/smisk/mvc/decorators.py", line 72, in f
return filter(leaf, *va, **kw)
File "/var/mysite/lib/mysite/admin_web/__init__.py", line 50, in add_authorized_user_to_rsp
return leaf(*va, **kw)
File "/usr/lib/python2.5/site-packages/smisk/mvc/routing.py", line 65, in __call__
return self._call_leaf(*args, **params)
File "/usr/lib/python2.5/site-packages/smisk/mvc/routing.py", line 59, in _call_leaf
return self.leaf(*args, **params)
File "/var/mysite/lib/smisk117compat.py", line 15, in f
return filter(leaf, *va, **kw)
File "/var/mysite/lib/smisk117compat.py", line 150, in filter
self.parameter: q.all(),
File "/var/lib/python-support/python2.5/sqlalchemy/orm/query.py", line 878, in all
return list(self)
File "/var/lib/python-support/python2.5/sqlalchemy/orm/query.py", line 938, in __iter__
return self._execute_and_instances(context)
File "/var/lib/python-support/python2.5/sqlalchemy/orm/query.py", line 941, in _execute_and_instances
result = self.session.execute(querycontext.statement, params=self._params, mapper=self.mapper, instance=self._refresh_instance)
File "/var/lib/python-support/python2.5/sqlalchemy/orm/session.py", line 628, in execute
return self.__connection(engine, close_with_result=True).execute(clause, params or {})
File "/var/lib/python-support/python2.5/sqlalchemy/engine/base.py", line 844, in execute
return Connection.executors[c](self, object, multiparams, params)
File "/var/lib/python-support/python2.5/sqlalchemy/engine/base.py", line 895, in execute_clauseelement
return self._execute_compiled(elem.compile(dialect=self.dialect, column_keys=keys, inline=len(params) > 1), distilled_params=params)
File "/var/lib/python-support/python2.5/sqlalchemy/engine/base.py", line 904, in _execute_compiled
context = self.__create_execution_context(compiled=compiled, parameters=distilled_params)
File "/var/lib/python-support/python2.5/sqlalchemy/engine/base.py", line 948, in __create_execution_context
return self.engine.dialect.create_execution_context(connection=self, **kwargs)
File "/var/lib/python-support/python2.5/sqlalchemy/databases/mysql.py", line 1474, in create_execution_context
return MySQLExecutionContext(self, connection, **kwargs)
File "/var/lib/python-support/python2.5/sqlalchemy/engine/default.py", line 179, in __init__
self.compiled_parameters = [compiled.construct_params(m) for m in parameters]
File "/var/lib/python-support/python2.5/sqlalchemy/sql/compiler.py", line 217, in construct_params
pd[self.bind_names[bindparam]] = bindparam.value()
File "/var/lib/python-support/python2.5/sqlalchemy/orm/strategies.py", line 288, in <lambda>
bindparam.value = lambda: mapper._get_committed_attr_by_column(instance, bind_to_col[bindparam.key])
File "/var/lib/python-support/python2.5/sqlalchemy/orm/mapper.py", line 974, in _get_committed_attr_by_column
return self._get_col_to_prop(column).getcommitted(obj._state, column)
AttributeError: 'str' object has no attribute '_state'

Guess I'll have to check the source and see if it somewhere replaces the parent object with a string. Because I checked that it was an object right before adding the user. Know this stack trace doesn't say much but thought that maybe you can see something that I can't.

Time for some detective work...

Jakob L.

unread,
Oct 27, 2011, 5:30:28 AM10/27/11
to sqlal...@googlegroups.com
I found the problem. I executed a query where I check against the parents name instad of the parent. Silly mistake, sorry for wasting your time. Since I write the query in a different place I didn't know it was actually the framework that executed it. 
Reply all
Reply to author
Forward
0 new messages