SQLAlchemy的'Connection'对象没有属性'_Inspector__engine'。
SQLAlchemy的'Connection'对象没有属性'_Inspector__engine'。
我想使用SQLAlchemy来读取未映射到对象的数据库(需要在开发时访问未知的数据库)。其中一个功能是读取不同表的列名。因此,我编写了这个连接器:\nMyConnector.py\n
import sqlalchemy as db class MyConnector: __engine = None def __init__(self, db_connection): self.__engine = db.create_engine(db_connection) def __get_table(self, tbl_name): metadata = db.MetaData() table = db.Table(tbl_name, metadata) inspector = db.inspect(self.__engine) inspector.reflect_table(table, None) return table def get_table_columns(self, tbl_name): table = self.__get_table(tbl_name) return table.columns.keys()
\n通过以下单元测试对其进行了测试:\nConnectorTest.py\n
import unittest from MyConnector import MyConnector class MyTestCase(unittest.TestCase): db_string = "sqlite:///myTest.db" expected_columns_user = ["id", "f_name", "l_name", "note"] expected_columns_address = ["id", "street", "number", "postal_code", "additional_information", "fk_user"] def test_get_table_columns_user(self): connector = MyConnector(self.db_string) answer = connector.get_table_columns("user") self.assertListEqual(self.expected_columns_user, answer) def test_get_table_columns_address(self): connector = MyConnector(self.db_string) answer = connector.get_table_columns("address") self.assertListEqual(self.expected_columns_address, answer) if __name__ == '__main__': unittest.main()
\nSQLite数据库仅包含以下两个空表:\n
CREATE TABLE user ( id INTEGER NOT NULL DEFAULT AUTO_INCREMENT, f_name VARCHAR, l_name VARCHAR, note VARCHAR, PRIMARY KEY ( id ) ); CREATE TABLE address ( id INTEGER NOT NULL DEFAULT AUTO_INCREMENT, street VARCHAR NOT NULL, number INTEGER, postal_code INTEGER NOT NULL, additional_information VARCHAR, fk_user INTEGER NOT NULL, PRIMARY KEY ( id ), FOREIGN KEY ( fk_user ) REFERENCES user(id) ON DELETE CASCADE );
\n测试test_get_table_columns_user
按预期工作。\n测试test_get_table_columns_address
引发错误:\n
Error Traceback (most recent call last): File "ConnectorTest.py", line 17, in test_get_table_columns_address answer = connector.get_table_columns("address") File "MyConnector.py", line 17, in get_table_columns table = self.__get_table(tbl_name) File "MyConnector.py", line 13, in __get_table inspector.reflect_table(table, None) File "venv\lib\site-packages\sqlalchemy\engine\reflection.py", line 802, in reflect_table reflection_options, File "venv\lib\site-packages\sqlalchemy\engine\reflection.py", line 988, in _reflect_fk **reflection_options File "", line 2, in __new__ File "venv\lib\site-packages\sqlalchemy\util\deprecations.py", line 298, in warned return fn(*args, **kwargs) File "venv\lib\site-packages\sqlalchemy\sql\schema.py", line 601, in __new__ metadata._remove_table(name, schema) File "venv\lib\site-packages\sqlalchemy\util\langhelpers.py", line 72, in __exit__ with_traceback=exc_tb, File "venv\lib\site-packages\sqlalchemy\util\compat.py", line 207, in raise_ raise exception File "venv\lib\site-packages\sqlalchemy\sql\schema.py", line 596, in __new__ table._init(name, metadata, *args, **kw) File "venv\lib\site-packages\sqlalchemy\sql\schema.py", line 676, in _init resolve_fks=resolve_fks, File "venv\lib\site-packages\sqlalchemy\sql\schema.py", line 705, in _autoload with insp._inspection_context() as conn_insp: File "AppData\Local\Programs\Python\Python37\lib\contextlib.py", line 112, in __enter__ return next(self.gen) File "venv\lib\site-packages\sqlalchemy\engine\reflection.py", line 217, in _inspection_context sub_insp = self._construct(self.__class__._init_connection, conn) File "venv\lib\site-packages\sqlalchemy\engine\reflection.py", line 117, in _construct init(self, bind) File "venv\lib\site-packages\sqlalchemy\engine\reflection.py", line 135, in _init_connection self.engine = connection.__engine AttributeError: 'Connection' object has no attribute '_Inspector__engine'
\n由于两个测试运行的代码完全相同,除了表名参数,因此我对结果感到非常困惑。\n使用谷歌,我找到了这个 PR:https://github.com/laughingman7743/PyAthena/pull/65/files\n似乎与此问题无关(引擎而不是连接)。\n有很多关于会话的帖子(例如Python SQLAlchemy Query: AttributeError: \'Connection\' object has no attribute \'contextual_connect\'或https://github.com/sqlalchemy/sqlalchemy/issues/4046)。这应该不重要,因为在这个上下文中使用检查器似乎甚至不需要调用engine.connect()
。\n为了排除潜在的锁定或类似问题,我还将test_get_table_columns_address
的参数更改为\"user\"
。这可以正确执行断言之前,显然不匹配。所以对我来说,这看起来是一个与表(-name?)相关的问题 - 这非常奇怪。\n有经验和了解SQLAlchemy的人能指出我的代码问题在哪里吗?提前谢谢!\nPython 3.7.4\nSQLAlchemy 1.4.20
问题出现的原因是依赖关系可能出现了混乱。通过更改venv来尝试不同版本的SQLAlchemy并编写具有上述描述行为的错误报告。因此,我多次使用以下命令更改了venv:
pip freeze > uninstall.txt pip uninstall -r uninstall.txt -y pip install -r requirements.txt
同时更改requirements.txt为几个不同的SQLAlchemy版本。请注意,requirements.txt始终只包含一个单独的要求(不同版本的SQLAlchemy)。
看到每个经过测试的版本都表现如预期并且通过了问题中的单元测试,我改回了1.4.20版本。即使是版本1.4.20,单元测试也成功了。
为了避免其他文件的可能影响,项目中始终只包含两个py文件和数据库。所以我认为我们可以排除项目本身的更改作为原因。我还尝试了使用下划线和双下划线"私有",测试成功了。所以我唯一的猜测是,最初的要求可能出了问题。不幸的是,我无法回退和检查第一个uninstall.txt文件,因为它被多次覆盖了。