SQLAlchemy与SQLite版本兼容异常及sqlalchemy-pysqlite3警告解决求助
问题与解决方案
环境与代码
使用SQLAlchemy 2.0.36搭配SQLite数据库,核心代码如下:
from sqlalchemy import create_engine, Column, Text, Integer from sqlalchemy.orm import declarative_base from sqlalchemy.orm import sessionmaker Base = declarative_base() class Person(Base): __tablename__ = "People" person_id = Column("person_id", Integer, primary_key=True) firstname = Column("first_name", Text) lastname = Column("last_name", Text) def __init__(self, personid, firstname, lastname): self.person_id = personid self.firstname = firstname self.lastname = lastname engine = create_engine("sqlite:///:memory:") Base.metadata.create_all(bind=engine) Session = sessionmaker(bind=engine) session = Session() person = Person(123, "hi", "bi") session.add(person) session.commit()
异常现象
- SQLite 3.7.17版本:代码运行正常
- SQLite 3.26.0版本:抛出错误
sqlite3.NotSupportedError: deterministic=True requires SQLite 3.8.3 or higher
该结果与预期相反,本该低版本报错、高版本正常运行。
尝试方案后的新问题
改用sqlalchemy-pysqlite3库,修改引擎创建语句为:
engine = create_engine("sqlite+pysqlite3:///:memory:")
原错误解决,但出现两个警告:
- 弃用警告:
SADeprecationWarning: The dbapi() classmethod on dialect classes has been renamed to import_dbapi(). Implement an import_dbapi() classmethod directly on class <class 'sqlalchemy_pysqlite3.SQLiteDialect_pysqlite3'> to remove this warning; the old .dbapi() classmethod may be maintained for backwards compatibility. - 性能警告:
SAWarning: Dialect sqlite:pysqlite will not make use of SQL compilation caching as it does not set the 'supports_statement_cache' attribute to True. This can have significant performance implications...
无侵入式解决警告的方法
1. 自定义方言类修复两个警告
通过子类化sqlalchemy-pysqlite3的方言类,补充缺失的方法和属性,无需修改原库代码:
from sqlalchemy_pysqlite3 import SQLiteDialect_pysqlite3 # 自定义修复后的SQLite方言 class FixedSQLiteDialect(SQLiteDialect_pysqlite3): @classmethod def import_dbapi(cls): # 复用原dbapi方法的逻辑,适配SQLAlchemy 2.0+的要求 return cls.dbapi() # 启用SQL编译缓存,消除性能警告 supports_statement_cache = True
2. 使用自定义方言创建引擎
修改引擎创建代码,指定使用上面的自定义方言:
engine = create_engine( "sqlite+pysqlite3:///:memory:", dialect=FixedSQLiteDialect() )
关于版本反常识报错的补充说明
SQLite 3.26.0报错的本质是Python标准库的sqlite3模块可能绑定了系统中更旧的SQLite版本(而非你安装的3.26.0)。sqlalchemy-pysqlite3会强制调用系统安装的SQLite库,从而解决版本不匹配问题。如果不想依赖第三方库,也可以通过升级Python版本(Python 3.10+内置的SQLite版本更高)来解决最初的报错。
内容的提问来源于stack exchange,提问作者Lilachr
相关产品推荐
相关产品推荐

