SQLAlchemy AutoMap AttributeError(尽管定义了主键)

Posted

技术标签:

【中文标题】SQLAlchemy AutoMap AttributeError(尽管定义了主键)【英文标题】:SQLAlchemy AutoMap AttributeError (despite having primary key defined) 【发布时间】:2021-08-03 09:52:51 【问题描述】:

我正在尝试将现有的 MS Access 数据库反映到新模型中。要将数据库链接到 SQLAlchemy,我正在使用

engine = create_engine("access+pyodbc://@db-dns")

由于数据库已经存在,我按照这篇文章的基本使用方案:https://docs.sqlalchemy.org/en/14/orm/extensions/automap.html

# reflect the table
Base.prepare(engine, reflect=True)

# mapped classes are now created with names by default
# matching that of the table name
Personen = Base.classes.ref_personen #here, 'ref_personen' is a table from my database

session = Session(engine)

当我尝试使用 Personen.query.all() 访问表时,我得到一个 AttributeError(错误日志见下文)。


编辑:要提出错误,我什至不必查询任何内容。我假设错误已经在这一行引起:Personen = Base.classes.ref_personen


通常,此错误的原因是由于未在外部数据库中定义主键。但是,对我来说并非如此。在我的 MS Access DB rel_personen 表中,定义了一个主键。

谢谢,感谢您对此主题的任何帮助!


(appenv4) C:\Users\Code\webapps4>flask run
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
c:\users\code\webapps4\appenv4\lib\site-packages\sqlalchemy\engine\reflection.py:919: SAWarning: The Access ODBC driver does not support the ODBC "SQLPrimaryKeys" function. get_pk_constraint() is returning an empty list.
  pk_cons = self.get_pk_constraint(
c:\users\code\webapps4\appenv4\lib\site-packages\sqlalchemy\engine\reflection.py:947: SAWarning: The Access ODBC driver does not support the ODBC "SQLForeignKeys" function. get_foreign_keys() is returning an empty list.
  fkeys = self.get_foreign_keys(
Traceback (most recent call last):
  File "c:\users\code\webapps4\appenv4\lib\site-packages\sqlalchemy\util\_collections.py", line 186, in __getattr__
    return self._data[key]
KeyError: 'ref_personen'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\anaconda3\lib\runpy.py", line 194, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "C:\Users\anaconda3\lib\runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "C:\Users\Code\webapps4\appenv4\Scripts\flask.exe\__main__.py", line 7, in <module>
  File "c:\users\code\webapps4\appenv4\lib\site-packages\flask\cli.py", line 990, in main
    cli.main(args=sys.argv[1:])
  File "c:\users\code\webapps4\appenv4\lib\site-packages\flask\cli.py", line 596, in main
    return super().main(*args, **kwargs)
  File "c:\users\code\webapps4\appenv4\lib\site-packages\click\core.py", line 1062, in main
    rv = self.invoke(ctx)
  File "c:\users\code\webapps4\appenv4\lib\site-packages\click\core.py", line 1668, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "c:\users\code\webapps4\appenv4\lib\site-packages\click\core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "c:\users\code\webapps4\appenv4\lib\site-packages\click\core.py", line 763, in invoke
    return __callback(*args, **kwargs)
  File "c:\users\code\webapps4\appenv4\lib\site-packages\click\decorators.py", line 84, in new_func
    return ctx.invoke(f, obj, *args, **kwargs)
  File "c:\users\code\webapps4\appenv4\lib\site-packages\click\core.py", line 763, in invoke
    return __callback(*args, **kwargs)
  File "c:\users\code\webapps4\appenv4\lib\site-packages\flask\cli.py", line 845, in run_command
    app = DispatchingApp(info.load_app, use_eager_loading=eager_loading)
  File "c:\users\code\webapps4\appenv4\lib\site-packages\flask\cli.py", line 321, in __init__
    self._load_unlocked()
  File "c:\users\code\webapps4\appenv4\lib\site-packages\flask\cli.py", line 346, in _load_unlocked
    self._app = rv = self.loader()
  File "c:\users\code\webapps4\appenv4\lib\site-packages\flask\cli.py", line 406, in load_app
    app = locate_app(self, import_name, None, raise_if_not_found=False)
  File "c:\users\code\webapps4\appenv4\lib\site-packages\flask\cli.py", line 273, in locate_app
    return find_best_app(script_info, module)
  File "c:\users\code\webapps4\appenv4\lib\site-packages\flask\cli.py", line 68, in find_best_app
    app = call_factory(script_info, app_factory)
  File "c:\users\code\webapps4\appenv4\lib\site-packages\flask\cli.py", line 119, in call_factory
    return app_factory(*args, **kwargs)
  File "C:\Users\Code\webapps4\app\__init__.py", line 19, in create_app
    from .zkl import zkl as zkl_bp
  File "C:\Users\Code\webapps4\app\zkl\__init__.py", line 6, in <module>
    from . import zkl_forms, zkl_views
  File "C:\Users\Code\webapps4\app\zkl\zkl_views.py", line 3, in <module>
    from .zkl_database import db_session, init_db
  File "C:\Users\Code\webapps4\app\zkl\zkl_database.py", line 12, in <module>
    Personen = Base.classes.ref_personen
  File "c:\users\code\webapps4\appenv4\lib\site-packages\sqlalchemy\util\_collections.py", line 188, in __getattr__
    raise AttributeError(key)
AttributeError: ref_personen

【问题讨论】:

【参考方案1】:

更新:sqlalchemy-access 1.1.0 版现在支持反射主键 (PK) 和外键 (FK) 约束。


(上一个答案)

正如堆栈跟踪中的一条警告消息所述:

SA 警告:Access ODBC 驱动程序不支持 ODBC“SQLPrimaryKeys”函数。 get_pk_constraint() 返回一个空列表。

这是 Access ODBC 驱动程序的一个已知问题。这里也有讨论

https://github.com/gordthompson/sqlalchemy-access/issues/9

这里

pyodbc - read primary keys from MS Access (MDB) database

【讨论】:

感谢您的回复!对此,我真的非常感激。鉴于您在数据库和访问方面的明显经验,您是否建议使用与 ms 访问不同的数据库服务与 sqlalchemy 结合使用? 我对方言做了一些调整。试试pip install git+https://github.com/gordthompson/sqlalchemy-access@dao_reflect 看看效果是否更好。 感谢您在这里的努力。但是,尝试更新版本时向我抛出了 ImportError: ImportError: DLL load failed while importing win32api: The specified procedure could not be found. 试试pip install pywin32。 (我将它添加为依赖项,但可能没有安装。) 安装 pywin32 对我有用。谢谢!

以上是关于SQLAlchemy AutoMap AttributeError(尽管定义了主键)的主要内容,如果未能解决你的问题,请参考以下文章

SQLAlchemy AutoMap AttributeError(尽管定义了主键)

sqlalchemy 如何使用 automap_base 生成(多对多)关系

如何使用Sqlalchemy中的automap_base处理AttributeError(key)? [重复]

SQLAlchemy 获取类对象而不是实际结果

sqlalchemy:查询数据库中的现有表

SQLAlchemy怎么在Oracle中自动建立映射