column_mapped_collection with argument presented as string doesn't play along

Issue #1863 resolved
Former user created an issue

When configuring a relation with column_mapped_collection(text("Class.property")), it doesn't seem be working as intended and causing a traceback (when reordering classes and using plain Class.property things work fine):

  File "utils/grumpy_sync.py", line 132, in package_sync
    p = cat.packages[ebuilds[0](ebuilds[0).key] = Package(ebuilds[0](0), mtime)
  File "/usr/lib64/python2.6/site-packages/sqlalchemy/orm/attributes.py", line 163, in __get__
    instance_dict(instance))
  File "/usr/lib64/python2.6/site-packages/sqlalchemy/orm/attributes.py", line 386, in get
    return self.set_committed_value(state, dict_, value)
  File "/usr/lib64/python2.6/site-packages/sqlalchemy/orm/attributes.py", line 799, in set_committed_value
    collection.append_without_event(item)
  File "/usr/lib64/python2.6/site-packages/sqlalchemy/orm/collections.py", line 551, in append_without_event
    getattr(self._data(), '_sa_appender')(item, _sa_initiator=False)
  File "/usr/lib64/python2.6/site-packages/sqlalchemy/orm/collections.py", line 1409, in set
    key = self.keyfunc(value)
  File "/usr/lib64/python2.6/site-packages/sqlalchemy/orm/collections.py", line 137, in keyfunc
    return m._get_state_attr_by_column(state, state.dict, cols[0](0))
  File "/usr/lib64/python2.6/site-packages/sqlalchemy/orm/mapper.py", line 1278, in _get_state_attr_by_column
    return self._get_col_to_prop(column)._getattr(state, dict_, column)
  File "/usr/lib64/python2.6/site-packages/sqlalchemy/orm/mapper.py", line 1264, in _get_col_to_prop
    prop = self._props.get(column.key, None)
AttributeError: '_TextClause' object has no attribute 'key'

Comments (9)

  1. Mike Bayer repo owner

    that usage is not supported, what documentation is leading you to attempt putting text() inside of column_mapped_collection() ?

  2. Former user Account Deleted

    Replying to zzzeek:

    that usage is not supported, what documentation is leading you to attempt putting text() inside of column_mapped_collection() ?

    When I just try to put "Class.package" then the mapper error tells me to use either text() or literal().

  3. Former user Account Deleted

    This is the where I got the text() idea:

    Traceback (most recent call last):
      File "models.py", line 9, in <module>
        class Category(Base):
      File "models.py", line 18, in Category
        collection_class=column_mapped_collection("Package.key"))
      File "/usr/lib64/python2.6/site-packages/sqlalchemy/orm/collections.py", line 132, in column_mapped_collection
        cols = [for q in util.to_list(mapping_spec)](expression._no_literals(q))
      File "/usr/lib64/python2.6/site-packages/sqlalchemy/sql/expression.py", line 977, in _no_literals
        "bound value." % element)
    sqlalchemy.exc.ArgumentError: Ambiguous literal: 'Package.key'.  Use the 'text()' function to indicate a SQL expression literal, or 'literal()' to indicate a bound value.
    
  4. Former user Account Deleted
    • changed status to open
    • removed status

    So what's the proper way to define column when using declarative syntax in case class is not yet defined like it is in attached file?

    Although one workaround is to reorder classes in such order: Ebuild < Package (maps: Ebuild.cpv) < Category (maps: Package.key), I don't really like it. So If column-based expression is the only possible argument, shall one fall back to attribute_mapped_collection?

  5. Mike Bayer repo owner

    The proper way for now is to either order things so they can be imported, or to add the relationship() after the fact, again after things can be imported. We could look into having the "collection_class" attribute accept a string overall though there is an awkwardness there that a user-defined collection class wouldn't be available.

  6. Log in to comment