- changed status to invalid
Can't have a relation and its supporting column with the same name
(original reporter: ged) This fails even when specifying allow_column_override to the mapper. The attached test case, produce the following traceback.
Traceback (most recent call last):
File "test_one_to_many_same_name.py", line 50, in <module>
session.flush()
File "/home/ged/devel/sqlalchemy/trunk/lib/sqlalchemy/orm/session.py", line 766, in flush
self.uow.flush(self, objects)
File "/home/ged/devel/sqlalchemy/trunk/lib/sqlalchemy/orm/unitofwork.py", line 233, in flush
flush_context.execute()
File "/home/ged/devel/sqlalchemy/trunk/lib/sqlalchemy/orm/unitofwork.py", line 445, in execute
UOWExecutor().execute(self, tasks)
File "/home/ged/devel/sqlalchemy/trunk/lib/sqlalchemy/orm/unitofwork.py", line 930, in execute
self.execute_save_steps(trans, task)
File "/home/ged/devel/sqlalchemy/trunk/lib/sqlalchemy/orm/unitofwork.py", line 948, in execute_save_steps
self.execute_dependencies(trans, task, False)
File "/home/ged/devel/sqlalchemy/trunk/lib/sqlalchemy/orm/unitofwork.py", line 959, in execute_dependencies
self.execute_dependency(trans, dep, False)
File "/home/ged/devel/sqlalchemy/trunk/lib/sqlalchemy/orm/unitofwork.py", line 942, in execute_dependency
dep.execute(trans, isdelete)
File "/home/ged/devel/sqlalchemy/trunk/lib/sqlalchemy/orm/unitofwork.py", line 895, in execute
self.processor.process_dependencies(self.targettask, [for elem in self.targettask.polymorphic_tosave_elements if elem.state is not None](elem.state), trans, delete=False)
File "/home/ged/devel/sqlalchemy/trunk/lib/sqlalchemy/orm/dependency.py", line 337, in process_dependencies
self._synchronize(state, child, None, False, uowcommit)
File "/home/ged/devel/sqlalchemy/trunk/lib/sqlalchemy/orm/dependency.py", line 377, in _synchronize
self.syncrules.execute(source, dest, dest, child, clearkeys)
File "/home/ged/devel/sqlalchemy/trunk/lib/sqlalchemy/orm/sync.py", line 95, in execute
rule.execute(source, dest, obj, child, clearkeys)
File "/home/ged/devel/sqlalchemy/trunk/lib/sqlalchemy/orm/sync.py", line 186, in execute
self._raise_col_to_prop(True)
File "/home/ged/devel/sqlalchemy/trunk/lib/sqlalchemy/orm/sync.py", line 134, in _raise_col_to_prop
raise exceptions.UnmappedColumnError("Can't execute sync rule for destination column '%s'; mapper '%s' does not map this column. Try using an explicit `foreign_keys` collection which does not include this column (or use a viewonly=True relation)." % (self.dest_column, self.dest_mapper))
sqlalchemy.exceptions.UnmappedColumnError: Can't execute sync rule for destination column 'parent.child'; mapper 'Mapper|Parent|parent' does not map this column. Try using an explicit `foreign_keys` collection which does not include this column (or use a viewonly=True relation).
FWIW: it was first reported as an Elixir ticket: http://elixir.ematia.de/trac/ticket/39
I'm personally not sure whether this should be allowed or not, but I don't see the point of having the allow_column_override option if this particular use case is not allowed.
Comments (3)
-
repo owner -
Account Deleted (original author: ged) I know SA needs the column, but, since the user clearly indicates he doesn't care about this column (ie doesn't want to access it -- a user usually think in terms of what he does/doesn't need, what the underlying library does or need), we could somehow have that column still present in a private (not accessible from the outside) or anonymous way so that the relation can still work. This is the behavior I'd expect when "allow_column_override" is set.
-
repo owner as discussed on IRC i think the foreign key attribute on the class being automatically "hidden" is an implicit behavior that's better suited for Elixir itself - elixir would place a foreign key column_property() on the mapper using a private name (like underscored or similar).
For SA, the "allow_column_override" flag is redundant versus "exclude_properties" and should probably be removed for that reason. Its usage has never been encouraged (except for its presence in the error message) and removing it will make it clearer that its up to the end user to re-target the same-named foreign key column. If you truly want a column ignored entirely, then using exclude_columns will make it clearer that thats what you're doing.
- Log in to comment
allow_column_override means, "I don't care about this column being part of my mapping, just get rid of it". It's a less relevant flag now that we have "exclude_properties" and "include_properties", then again it still may be convenient for those cases when you just want to build relation names that may or may not step on columns you don't care about.
However in this case, SQLAlchemy clearly needs access to the "parent_table.c.column" column in order to handle the relation, like the error indicates. So the correct pattern for this specific case is: