the caching routine for datatypes is matching up the names of the parameters to 
the internal state of the object.   any name will reproduce as long as you name 
the parameters and internal attributes the same.

On Thu, May 6, 2021, at 11:52 AM, Steven James wrote:
> I originally came to that conclusion, and I agree that replacing it with a 
> tuple does fix it, but I still can't explain why using a different parameter 
> name also fixes it.
> 
> On Thursday, 6 May 2021 at 11:46:53 UTC-4 Mike Bayer wrote:
>> __
>> 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+...@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/e3e699b6-3b74-40b5-8213-58878ee23b8bn%40googlegroups.com
>  
> <https://groups.google.com/d/msgid/sqlalchemy/e3e699b6-3b74-40b5-8213-58878ee23b8bn%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/7a87c91a-efc3-4eb1-a078-5a1a42ab1991%40www.fastmail.com.

Reply via email to