db = SQLAlchemy() 与 db.init_app(app) 到底做了什么?数据库是在什么时候连上的?SQLite 文件落在哪?连不上数据库什么时候才会知道?这篇用一个真实的 PostgreSQL 实例数连接数,把答案逐项量出来。
init_app 之前 PG 上的连接数: 0 第一次 init_app 用时 56 ms(包含第一次导入 psycopg 等驱动),同一进程里再对另一个应用 init_app 只要 0.16 ms init_app 之后:0;app.extensions["sqlalchemy"] is db → True db.engine 的类型: Engine | 连接池: QueuePool (pool_size=5) | db.engines 的键: [None] 访问 db.engine 之后连接数: 0 第一次执行 SQL 之后连接数:1(第一次执行 6.4 ms) 第二次执行 0.69 ms 离开 app_context 之后连接数(session 被 remove,连接还给池,但池里仍保留): 1
init_app 之后 instance 目录存在: True | 文件: [] engine.url: sqlite:///<tmp>/instance/app.db 执行 SQL 之前文件存在: False 执行 SQL 之后文件存在: True 连接池类型: QueuePool sqlite 内存库的连接池: StaticPool
pool_size=2 max_overflow=1 pre_ping=True recycle=300 db.engines 的键: ['other', None] | 绑定库的引擎: sqlite:///<实验目录>/instance/other.db
还没 init_app 就定义了模型:db.metadata.tables = ['user'] | __tablename__ = user 上下文外 create_all → Working outside of application context. create_all 之后 PG 里的表: user
同一个应用 init_app 两次 → A 'SQLAlchemy' instance has already been registered on this Flask app. Import and use that instance instead. 同一个应用上下文里 db.session() 两次是同一个对象: True 嵌套的新应用上下文里是不同的 session: True 离开上下文后原 session 是否还在事务中 → False
没有 URI → RuntimeError Either 'SQLALCHEMY_DATABASE_URI' or 'SQLALCHEMY_BINDS' must be set. 未知方言的 URI 在 init_app 时就报错 → NoSuchModuleError Can't load plugin: sqlalchemy.dialects:nosuchdb 端口没人监听的 PG URI:init_app 成功; 第一次执行 SQL 才报错 → OperationalError