this is a regression in SQLAlchemy in that the TypeDecorator is being applied 
to caching without giving the end user any clue or API to control this process.

the name "choices" is not significant, it's that the parameter as given is 
trying to be part of a cache key, so turn this into a tuple for now to resolve:


class AltType(TypeDecorator):
    impl = Unicode(255)

    def __init__(self, choices):
        self.choices = tuple(choices)
        super(AltType, self).__init__()


https://github.com/sqlalchemy/sqlalchemy/issues/6436



On Thu, May 6, 2021, at 11:08 AM, Steven James wrote:
> This one is baffling me. The following example throws an exception about an 
> unhashable type, related (I think) to the new query caching in 1.4. However, 
> if I change the parameter name to AltType.__init__ to ANYTHING other than 
> `choices`, it works fine. I can't find any reference to the name `choices` in 
> the sqlalchemy codebase.
> 
> So why can't I use `choices` as a parameter name here? The answer might be 
> related to the AnnotatedColumn in the generated expression but that's about 
> as far as I've gotten.
> 
> ```
> # sqlalchemy 1.4.x
> 
> from sqlalchemy import Column, Integer, create_engine, TypeDecorator, Unicode
> from sqlalchemy.orm import sessionmaker, as_declarative, declared_attr
> 
> 
> class AltType(TypeDecorator):
>     impl = Unicode(255)
> 
>     def __init__(self, choices):
>         self.choices = choices
>         super(AltType, self).__init__()
> 
> 
> @as_declarative()
> class Base(object):
>     @declared_attr
>     def __tablename__(cls):
>         return cls.__name__.lower()
> 
>     pk = Column(Integer, primary_key=True)
> 
> 
> class MyClass(Base):
>     d = Column(AltType(['a', 'list', 'here']))
> 
> 
> if __name__ == '__main__':
>     e = create_engine('sqlite://', echo=True)
>     conn = e.connect()
> 
>     Base.metadata.create_all(e)
> 
>     s = sessionmaker(e)()
>     q = s.query(MyClass).filter(MyClass.d == 'search_str')
>     
>     result = q.first()  # <---- error here
>     print(result)
> 
> ```
> 
> result:
> ```
> Traceback (most recent call last):
>   File "...\scratch_78.py", line 36, in <module>
>     results = q.first()
>   File "...\\lib\site-packages\sqlalchemy\orm\query.py", line 2750, in first
>     return self.limit(1)._iter().first()
>   File "...\\lib\site-packages\sqlalchemy\orm\query.py", line 2834, in _iter
>     result = self.session.execute(
>   File "...\\lib\site-packages\sqlalchemy\orm\session.py", line 1675, in 
> execute
>     result = conn._execute_20(statement, params or {}, execution_options)
>   File "...\\lib\site-packages\sqlalchemy\engine\base.py", line 1521, in 
> _execute_20
>     return meth(self, args_10style, kwargs_10style, execution_options)
>   File "...\\lib\site-packages\sqlalchemy\sql\elements.py", line 313, in 
> _execute_on_connection
>     return connection._execute_clauseelement(
>   File "...\\lib\site-packages\sqlalchemy\engine\base.py", line 1382, in 
> _execute_clauseelement
>     compiled_sql, extracted_params, cache_hit = elem._compile_w_cache(
>   File "...\\lib\site-packages\sqlalchemy\sql\elements.py", line 531, in 
> _compile_w_cache
>     compiled_sql = compiled_cache.get(key)
>   File "...\\lib\site-packages\sqlalchemy\util\_collections.py", line 918, in 
> get
>     item = dict.get(self, key, default)
> TypeError: unhashable type: 'list'
> ```
> 
> -Steven James
> 

> -- 
> SQLAlchemy - 
> The Python SQL Toolkit and Object Relational Mapper
>  
> http://www.sqlalchemy.org/
>  
> To post example code, please provide an MCVE: Minimal, Complete, and 
> Verifiable Example. See http://stackoverflow.com/help/mcve for a full 
> description.
> --- 
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to sqlalchemy+unsubscr...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/sqlalchemy/3e863503-4afa-44c3-b54a-4fb26ae5e8c8n%40googlegroups.com
>  
> <https://groups.google.com/d/msgid/sqlalchemy/3e863503-4afa-44c3-b54a-4fb26ae5e8c8n%40googlegroups.com?utm_medium=email&utm_source=footer>.

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sqlalchemy/3f1abfe6-c217-4dfe-bcbf-997ed28dfc7c%40www.fastmail.com.

Reply via email to