your stack trace shows a different event hook that's causing the problem. 
codebase/database/__init__.py, so you want to move that event to 
before_mapper_configured:

> File "/codebase_mountpoint/codebase/database/__init__.py", line 177, in 
> set_serialize_map
>     for c in visible_table_columns:
>   File "/codebase_mountpoint/codebase/database/__init__.py", line 175, in 
> <lambda>
>     lambda x: cls.get_property_name_from_column(x) not in negatives,
>   File "/codebase_mountpoint/codebase/database/__init__.py", line 106, in 
> get_property_name_from_column
>     return sqlalchemy.inspect(cls).get_property_by_column(column_obj).key

On Sat, Oct 9, 2021, at 11:53 PM, niuji...@gmail.com wrote:
> Thank you Mike! My event-hooking code is like this:
> 
> @sqlalchemy.event.listens_for(_MyBase, "class_instrument")
> def set_serialize_map(cls):
>     module_logger.info(
>         f"<set_serialize_map> for {cls.__name__} is just invoked!")
>     ...
> 
> 
> 
> Here is the stack trace:
> 
> 2021-10-10 03:47:34 AM database MainThread 140107141936960 INFO 
> <set_serialize_map> for GeoAreaVariantName is just invoked!
> Traceback (most recent call last):
>   File "main.py", line 101, in <module>
>     cherrypy.quickstart(root=HomePage_Server(),
>   File "main.py", line 50, in __init__
>     self._collect_subunit_servers()
>   File "main.py", line 73, in _collect_subunit_servers
>     unit_server = importlib.import_module(
>   File "/usr/lib/python3.8/importlib/__init__.py", line 127, in import_module
>     return _bootstrap._gcd_import(name[level:], package, level)
>   File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
>   File "<frozen importlib._bootstrap>", line 991, in _find_and_load
>   File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
>   File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
>   File "<frozen importlib._bootstrap_external>", line 848, in exec_module
>   File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
>   File "/codebase_mountpoint/codebase/geography_server.py", line 14, in 
> <module>
>     from database.geography_schema import *
>   File "/codebase_mountpoint/codebase/database/geography_schema.py", line 19, 
> in <module>
>     class GeoArea(my_mixins.HasVariantName_Mixin, dal.Base):
>   File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/orm/decl_api.py", 
> line 72, in __init__
>     _as_declarative(reg, cls, dict_)
>   File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/orm/decl_base.py", 
> line 126, in _as_declarative
>     return _MapperConfig.setup_mapping(registry, cls, dict_, None, {})
>   File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/orm/decl_base.py", 
> line 177, in setup_mapping
>     return cfg_cls(registry, cls_, dict_, table, mapper_kw)
>   File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/orm/decl_base.py", 
> line 299, in __init__
>     self._scan_attributes()
>   File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/orm/decl_base.py", 
> line 557, in _scan_attributes
>     ret = getattr(cls, name)
>   File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/orm/decl_api.py", 
> line 237, in __get__
>     reg[desc] = obj = desc.fget(cls)
>   File "/codebase_mountpoint/codebase/database/my_mixins.py", line 39, in 
> variant_names
>     cls.VariantName = type(
>   File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/orm/decl_api.py", 
> line 72, in __init__
>     _as_declarative(reg, cls, dict_)
>   File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/orm/decl_base.py", 
> line 126, in _as_declarative
>     return _MapperConfig.setup_mapping(registry, cls, dict_, None, {})
>   File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/orm/decl_base.py", 
> line 177, in setup_mapping
>     return cfg_cls(registry, cls_, dict_, table, mapper_kw)
>   File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/orm/decl_base.py", 
> line 314, in __init__
>     self._early_mapping(mapper_kw)
>   File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/orm/decl_base.py", 
> line 200, in _early_mapping
>     self.map(mapper_kw)
>   File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/orm/decl_base.py", 
> line 992, in map
>     mapper_cls(self.cls, self.local_table, **self.mapper_args),
>   File "<string>", line 2, in __init__
>   File 
> "/usr/local/lib/python3.8/dist-packages/sqlalchemy/util/deprecations.py", 
> line 298, in warned
>     return fn(*args, **kwargs)
>   File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/orm/mapper.py", 
> line 682, in __init__
>     self._configure_class_instrumentation()
>   File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/orm/mapper.py", 
> line 1228, in _configure_class_instrumentation
>     manager = instrumentation.register_class(
>   File 
> "/usr/local/lib/python3.8/dist-packages/sqlalchemy/orm/instrumentation.py", 
> line 574, in register_class
>     manager._update_state(
>   File 
> "/usr/local/lib/python3.8/dist-packages/sqlalchemy/orm/instrumentation.py", 
> line 154, in _update_state
>     self._finalize()
>   File 
> "/usr/local/lib/python3.8/dist-packages/sqlalchemy/orm/instrumentation.py", 
> line 163, in _finalize
>     _instrumentation_factory.dispatch.class_instrument(self.class_)
>   File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/event/attr.py", 
> line 343, in __call__
>     fn(*args, **kw)
>   File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/orm/events.py", 
> line 79, in listen
>     return fn(target_cls, *arg)
>   File "/codebase_mountpoint/codebase/database/__init__.py", line 177, in 
> set_serialize_map
>     for c in visible_table_columns:
>   File "/codebase_mountpoint/codebase/database/__init__.py", line 175, in 
> <lambda>
>     lambda x: cls.get_property_name_from_column(x) not in negatives,
>   File "/codebase_mountpoint/codebase/database/__init__.py", line 106, in 
> get_property_name_from_column
>     return sqlalchemy.inspect(cls).get_property_by_column(column_obj).key
>   File "/usr/local/lib/python3.8/dist-packages/sqlalchemy/orm/mapper.py", 
> line 1998, in get_property_by_column
>     return self._columntoproperty[column]
> AttributeError: 'Mapper' object has no attribute '_columntoproperty'
> 
> On Friday, October 8, 2021 at 2:12:14 PM UTC-7 Mike Bayer wrote:
>> 
>> 
>> On Fri, Oct 8, 2021, at 4:13 PM, niuji...@gmail.com wrote:
>>> Thanks for this very important information!
>>> 
>>> If I do want to utilize the mapper functions at this stage, what can I do? 
>>> currently I have this error showing up:
>>> 
>>> AttributeError: 'Mapper' object has no attribute '_columntoproperty'
>> 
>> you would need to show me a stack trace on that.  however, depending on 
>> which event you are using to get at the mapper, it may not be initialized 
>> yet (can confirm that class_instrument() event is too early if access to the 
>> internals of the mapper is required).      as stated previously, the best 
>> event to use when a class is first mapped but before the full span of 
>> mappings have been considered is the before_mapper_configured() event (can 
>> confirm _columntoproperty is available at that stage).
>> 
>> 
>> 
>>> 
>>> On Friday, October 8, 2021 at 6:58:02 AM UTC-7 Mike Bayer wrote:
>>>> 
>>>> 
>>>> On Fri, Oct 8, 2021, at 7:09 AM, niuji...@gmail.com wrote:
>>>>> In order to make sure that the mapped class is fully ready, I chose the 
>>>>> latest point, namely `class_instrument`.
>>>>> However, it seems that at that moment the `__mapper__` attribute is not 
>>>>> available.
>>>>> When I tried 
>>>>>   return cls.__mapper__.get_property_by_column(column_obj).key
>>>>> 
>>>>> I got:
>>>>>  AttributeError: type object 'GeoAreaVariantName' has no attribute 
>>>>> '__mapper__'
>>>>> 
>>>>> Is this a bug or a feature?
>>>> 
>>>> it's a normal behavior, that event is called before mapping has been 
>>>> established.
>>>> 
>>>> but also, the "__mapper__" attribute is a convenience feature that should 
>>>> not be relied upon at this stage.  the correct way to get the mapper for a 
>>>> class is to use the sqlalchemy.inspect() function, i.e.  mapper = 
>>>> inspect(class).
>>>> 
>>>> 
>>>> 
>>>> 
>>>>> 
>>>>> On Wednesday, October 6, 2021 at 5:36:22 AM UTC-7 Mike Bayer wrote:
>>>>>> __
>>>>>> events that occur around this time include
>>>>>> 
>>>>>> this one claims it's before:
>>>>>> 
>>>>>> https://docs.sqlalchemy.org/en/14/orm/events.html#sqlalchemy.orm.MapperEvents.instrument_class
>>>>>> 
>>>>>> this one says after:
>>>>>> 
>>>>>> https://docs.sqlalchemy.org/en/14/orm/events.html#sqlalchemy.orm.InstrumentationEvents.class_instrument
>>>>>> 
>>>>>> this one is definitely after and is usually fine for anything that needs 
>>>>>> to happen for mapped classes before they are reconciled against other 
>>>>>> classes:
>>>>>> 
>>>>>> https://docs.sqlalchemy.org/en/14/orm/events.html#sqlalchemy.orm.MapperEvents.before_mapper_configured
>>>>>> 
>>>>>> 
>>>>>> On Wed, Oct 6, 2021, at 4:48 AM, niuji...@gmail.com wrote:
>>>>>>> I want to do some after processing on each class that is just put into 
>>>>>>> the class_registry. Is there a event hook for this? 
>>>>>>> 
>>>>>>> 
>>>>>>> -- 
>>>>>>> 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/6ec43831-d59e-4343-99cf-dce3773a1216n%40googlegroups.com
>>>>>>>  
>>>>>>> <https://groups.google.com/d/msgid/sqlalchemy/6ec43831-d59e-4343-99cf-dce3773a1216n%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+...@googlegroups.com.
>>>>> To view this discussion on the web visit 
>>>>> https://groups.google.com/d/msgid/sqlalchemy/066675cb-164a-4f61-9764-15ac402b6a3bn%40googlegroups.com
>>>>>  
>>>>> <https://groups.google.com/d/msgid/sqlalchemy/066675cb-164a-4f61-9764-15ac402b6a3bn%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+...@googlegroups.com.
>>> To view this discussion on the web visit 
>>> https://groups.google.com/d/msgid/sqlalchemy/fb457c38-74a2-4ce6-bb1c-35157347fd9fn%40googlegroups.com
>>>  
>>> <https://groups.google.com/d/msgid/sqlalchemy/fb457c38-74a2-4ce6-bb1c-35157347fd9fn%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/250c0fe7-2389-41e5-b86c-32065b9c9cean%40googlegroups.com
>  
> <https://groups.google.com/d/msgid/sqlalchemy/250c0fe7-2389-41e5-b86c-32065b9c9cean%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/63a58eec-0334-448c-81c5-c6cd95db6bb3%40www.fastmail.com.

Reply via email to