Note: If both ORM classes are placed in the same file, the documentation builds successfully.
Running Sphinx v9.1.0
loading translations [en]... done
making output directory... done
loading intersphinx inventory 'sqlalchemy' from https://docs.sqlalchemy.org/objects.inv ...
intersphinx inventory has moved: https://docs.sqlalchemy.org/objects.inv -> https://docs.sqlalchemy.org/en/20/objects.inv
building [mo]: targets for 0 po files that are out of date
writing output...
building [html]: targets for 1 source files that are out of date
updating environment: [new config] 1 added, 0 changed, 0 removed
reading sources... [100%] index
WARNING: autodoc: failed to import 'orm2' from module 'autodoc_sqlalchemy'; the following exception was raised:
Traceback (most recent call last):
File "C:\Users\vivodi\Projects\autodoc_sqlalchemy\.venv\Lib\site-packages\sphinx\ext\autodoc\_dynamic\_importer.py", line 221, in _import_module
module = importlib.import_module(modname)
File "C:\Users\vivodi\AppData\Roaming\uv\python\cpython-3.14-windows-x86_64-none\Lib\importlib\__init__.py", line 88, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<frozen importlib._bootstrap>", line 1398, in _gcd_import
File "<frozen importlib._bootstrap>", line 1371, in _find_and_load
File "<frozen importlib._bootstrap>", line 1342, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 938, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 762, in exec_module
File "<frozen importlib._bootstrap>", line 491, in _call_with_frames_removed
File "C:\Users\vivodi\Projects\autodoc_sqlalchemy\autodoc_sqlalchemy\orm2.py", line 6, in <module>
class ORM2(Base):
__tablename__ = "orm2"
id: Mapped[int] = mapped_column(primary_key=True)
File "C:\Users\vivodi\Projects\autodoc_sqlalchemy\.venv\Lib\site-packages\sqlalchemy\orm\decl_api.py", line 849, in __init_subclass__
_as_declarative(cls._sa_registry, cls, cls.__dict__)
~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\vivodi\Projects\autodoc_sqlalchemy\.venv\Lib\site-packages\sqlalchemy\orm\decl_base.py", line 245, in _as_declarative
return _MapperConfig.setup_mapping(registry, cls, dict_, None, {})
~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\vivodi\Projects\autodoc_sqlalchemy\.venv\Lib\site-packages\sqlalchemy\orm\decl_base.py", line 326, in setup_mapping
return _ClassScanMapperConfig(
registry, cls_, dict_, table, mapper_kw
)
File "C:\Users\vivodi\Projects\autodoc_sqlalchemy\.venv\Lib\site-packages\sqlalchemy\orm\decl_base.py", line 562, in __init__
self._scan_attributes()
~~~~~~~~~~~~~~~~~~~~~^^
File "C:\Users\vivodi\Projects\autodoc_sqlalchemy\.venv\Lib\site-packages\sqlalchemy\orm\decl_base.py", line 866, in _scan_attributes
table_args = cls_as_Decl.__table_args__
^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: type object 'ORM2' has no attribute '__table_args__'. Did you mean: '__tablename__'?
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\vivodi\Projects\autodoc_sqlalchemy\.venv\Lib\site-packages\sphinx\ext\autodoc\_dynamic\_importer.py", line 131, in _import_from_module_and_path
module = _import_module(module_name, try_reload=True)
File "C:\Users\vivodi\Projects\autodoc_sqlalchemy\.venv\Lib\site-packages\sphinx\ext\autodoc\_dynamic\_importer.py", line 233, in _import_module
raise ImportError(exc, traceback.format_exc()) from exc
ImportError: (AttributeError("type object 'ORM2' has no attribute '__table_args__'"), 'Traceback (most recent call last):\n File "C:\\Users\\vivodi\\Projects\\autodoc_sqlalchemy\\.venv\\Lib\\site-packages\\sphinx\\ext\\autodoc\\_dynamic\\_importer.py", line 221, in _import_module\n module = importlib.import_module(modname)\n File "C:\\Users\\vivodi\\AppData\\Roaming\\uv\\python\\cpython-3.14-windows-x86_64-none\\Lib\\importlib\\__init__.py", line 88, in import_module\n return _bootstrap._gcd_import(name[level:], package, level)\n ~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File "<frozen importlib._bootstrap>", line 1398, in _gcd_import\n File "<frozen importlib._bootstrap>", line 1371, in _find_and_load\n File "<frozen importlib._bootstrap>", line 1342, in _find_and_load_unlocked\n File "<frozen importlib._bootstrap>", line 938, in _load_unlocked\n File "<frozen importlib._bootstrap_external>", line 762, in exec_module\n File "<frozen importlib._bootstrap>", line 491, in _call_with_frames_removed\n File "C:\\Users\\vivodi\\Projects\\autodoc_sqlalchemy\\autodoc_sqlalchemy\\orm2.py", line 6, in <module>\n class ORM2(Base):\n __tablename__ = "orm2"\n id: Mapped[int] = mapped_column(primary_key=True)\n File "C:\\Users\\vivodi\\Projects\\autodoc_sqlalchemy\\.venv\\Lib\\site-packages\\sqlalchemy\\orm\\decl_api.py", line 849, in __init_subclass__\n _as_declarative(cls._sa_registry, cls, cls.__dict__)\n ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File "C:\\Users\\vivodi\\Projects\\autodoc_sqlalchemy\\.venv\\Lib\\site-packages\\sqlalchemy\\orm\\decl_base.py", line 245, in _as_declarative\n return _MapperConfig.setup_mapping(registry, cls, dict_, None, {})\n ~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n File "C:\\Users\\vivodi\\Projects\\autodoc_sqlalchemy\\.venv\\Lib\\site-packages\\sqlalchemy\\orm\\decl_base.py", line 326, in setup_mapping\n return _ClassScanMapperConfig(\n registry, cls_, dict_, table, mapper_kw\n )\n File "C:\\Users\\vivodi\\Projects\\autodoc_sqlalchemy\\.venv\\Lib\\site-packages\\sqlalchemy\\orm\\decl_base.py", line 562, in __init__\n self._scan_attributes()\n ~~~~~~~~~~~~~~~~~~~~~^^\n File "C:\\Users\\vivodi\\Projects\\autodoc_sqlalchemy\\.venv\\Lib\\site-packages\\sqlalchemy\\orm\\decl_base.py", line 866, in _scan_attributes\n table_args = cls_as_Decl.__table_args__\n ^^^^^^^^^^^^^^^^^^^^^^^^^^\nAttributeError: type object \'ORM2\' has no attribute \'__table_args__\'. Did you mean: \'__tablename__\'?\n')
[autodoc.import_object]
looking for now-outdated files... none found
pickling environment... done
checking consistency... done
preparing documents... done
copying assets...
copying static files...
Writing evaluated template result to C:\Users\vivodi\Projects\autodoc_sqlalchemy\docs\_build\html\_static\basic.css
Writing evaluated template result to C:\Users\vivodi\Projects\autodoc_sqlalchemy\docs\_build\html\_static\documentation_options.js
Writing evaluated template result to C:\Users\vivodi\Projects\autodoc_sqlalchemy\docs\_build\html\_static\language_data.js
Writing evaluated template result to C:\Users\vivodi\Projects\autodoc_sqlalchemy\docs\_build\html\_static\alabaster.css
copying static files: done
copying extra files...
copying extra files: done
copying assets: done
writing output... [100%] index
generating indices... genindex py-modindex done
writing additional pages... search done
dumping search index in English (code: en)... done
dumping object inventory... done
build succeeded, 1 warning.
The HTML pages are in _build\html.
autodoc_sqlalchemy/
├── __init__.py
├── orm1.py
└── orm2.py
.. automodule:: autodoc_sqlalchemy.orm1
:members:
:private-members:
:show-inheritance:
:undoc-members:
.. automodule:: autodoc_sqlalchemy.orm2
:members:
:private-members:
:show-inheritance:
:undoc-members:
Platform: win32; (Windows-11-10.0.26200-SP0)
Python version: 3.14.0 (main, Nov 19 2025, 22:43:52) [MSC v.1944 64 bit (AMD64)])
Python implementation: CPython
Sphinx version: 9.1.0
Docutils version: 0.22.4
Jinja2 version: 3.1.6
Pygments version: 2.21.0
Describe the bug
When using
sphinx.ext.autodocto document SQLAlchemy ORM models defined in separate files, Sphinx fails to import the second module and raises anAttributeError: type object 'ORM2' has no attribute '__table_args__'.Note: If both ORM classes are placed in the same file, the documentation builds successfully.
Update: Setting
autodoc_use_legacy_class_based = Truesolves the issue. This is a sub-issue of TRACKING: Problems in the new implementation of autodoc.How to Reproduce
Project Structure:
autodoc_sqlalchemy/__init__.pyautodoc_sqlalchemy/orm1.pyautodoc_sqlalchemy/orm2.pydocs/index.rstgit clonemethod to reproduce:git clone https://github.com/vivodi/autodoc-sqlalchemy-demo.git cd autodoc-sqlalchemy-demo uv sync uv run sphinx-build -M html docs docs/_buildEnvironment Information
Sphinx extensions
Additional context
sqlalchemy version: 2.0.52
I also reported this issue to SQLAlchemy, but it remains unresolved. sqlalchemy/sqlalchemy#13527