create_engine 中的烧瓶 SQLAlchemy KeyError 'False'

Posted

技术标签:

【中文标题】create_engine 中的烧瓶 SQLAlchemy KeyError \'False\'【英文标题】:Flask SQLAlchemy KeyError 'False' in create_enginecreate_engine 中的烧瓶 SQLAlchemy KeyError 'False' 【发布时间】:2021-12-04 19:04:20 【问题描述】:

我有一个烧瓶应用程序,它使用 sqlalchemy 与 mysql 连接。数据库查询发生了一个奇怪的错误。

`Traceback(最近一次调用最后一次): 调用中的文件“/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/sqlalchemy/util/_collections.py”,第 1008 行 返回 self.registry[key] KeyError:

在处理上述异常的过程中,又发生了一个异常:

Traceback(最近一次调用最后一次):文件 “/home/Desktop/work/nesting-app/server/users/routes.py”,行 28、在 register_new_user 如果 form.validate_on_submit(): 文件“/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/flask_wtf/form.py”, 第 100 行,在 validate_on_submit 返回 self.is_submitted() 和 self.validate() 文件“/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/wtforms/form.py”, 第 318 行,有效 return super(Form, self).validate(extra) File "/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/wtforms/form.py", 第 150 行,有效 如果不是 field.validate(self,extra):文件“/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/wtforms/fields/core.py”, 第 226 行,有效 stop_validation = self._run_validation_chain(form, chain) 文件 "/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/wtforms/fields/core.py", 第 246 行,在 _run_validation_chain 验证器(表单,自我)文件“/home/Desktop/work/nesting-app/server/users/forms.py”,行 43,在 validate_email 中 用户 = User.query.filter_by(email=email.data).first() 文件“/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/flask_sqlalchemy/init.py", 第 552 行,在 get 返回 type.query_class(mapper, session=self.sa.session()) 文件“/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/sqlalchemy/orm/scoping.py” , 第 47 行,在 call 中 sess = self.registry() 文件“/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/sqlalchemy/util/collections.py”,第 1010 行,在 打电话 返回 self.registry.setdefault(key, self.createfunc()) 文件“/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/sqlalchemy/orm/session.py”, 第 4171 行,在 调用 return self.class(**local_kw) 文件 "/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/flask_sqlalchemy/init.py ", 第 176 行,在 init 中 bind = options.pop('bind', None) 或 db.engine File "/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/flask_sqlalchemy/init.py", 第 998 行,在引擎中 返回 self.get_engine() 文件 "/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/flask_sqlalchemy/init.py", 第 1017 行,在 get_engine 中 返回 connector.get_engine() 文件“/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/flask_sqlalchemy/init.py”, 第 594 行,在 get_engine 中 self._engine = rv = self._sa.create_engine(sa_url, options) 文件 "/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/flask_sqlalchemy/init.py", 第 1027 行,在 create_engine return sqlalchemy.create_engine(sa_url, **engine_opts) File "", line 2, in create_engine File “/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/sqlalchemy/util/deprecations.py”,第 298 行,警告 返回 fn(*args, **kwargs) 文件“/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/sqlalchemy/engine/create.py”, 第 661 行,在 create_engine engine = engineclass(pool, dialect, u, **engine_args) File "/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/sqlalchemy/engine/base.py", 第 2758 行,在 init 中 self.echo = echo 文件“/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/sqlalchemy/log.py”, 第 225 行,在 set 中 instance_logger(instance, echoflag=value) 文件“/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/sqlalchemy/log.py”, 第 202 行,在 instance_logger 中 logger = InstanceLogger(echoflag, name) 文件“/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/sqlalchemy/log.py”, 第 103 行,在 init 中 如果 self._echo_map[echo]

这里是 config.py

from os import environ, path
from dotenv import load_dotenv
from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent.parent
load_dotenv(path.join(BASE_DIR, '.env'))


class Config:
    SECRET_KEY = environ.get('SECRET_KEY')
    SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://user:password@127.0.0.1:3306/dbname'
    # SQLALCHEMY_ECHO: When set to 'True', Flask-SQLAlchemy will log all database
    # activity to Python's stderr for debugging purposes.
    SQLALCHEMY_ECHO = environ.get('SQLALCHEMY_ECHO')
    #  To suppress the warning "this option takes a lot of system resources" set
    SQLALCHEMY_TRACK_MODIFICATIONS = environ.get('SQLALCHEMY_TRACK_MODIFICATIONS')

这里是 init.py

db = SQLAlchemy()
bcrypt = Bcrypt()
login_manager = LoginManager()
login_manager.login_view = 'users.login'
mail = Mail()
csrf = CSRFProtect()


def create_app(config_class=Config):
    flask_app = Flask(__name__)
    flask_app.config.from_object(config_class)

    db.init_app(flask_app)
    bcrypt.init_app(flask_app)
    login_manager.init_app(flask_app)
    mail.init_app(flask_app)
    csrf.init_app(flask_app)

我尝试过使用不同的连接字符串:

SQLALCHEMY_DATABASE_URI=mysql+mysqlconnector://user:pass@localhost:3306/dbname

SQLALCHEMY_DATABASE_URI=mysql+mysqlconnector://user:pass@localhost/dbname

SQLALCHEMY_DATABASE_URI=mysql+mysqlconnector://user:pass@127.0.0.1:3306/dbname

感谢您的帮助。

【问题讨论】:

【参考方案1】:

SQLAlchemy 的 create_engine 函数的 echo 标志接受一组有限的值:NoneFalseTrue"debug" (source)。

回溯显示 字符串 "False" 正在被传递:KeyError: 'False'。实际上,可以通过传递任何字符串(“debug”除外)作为create_engineecho 标志的值来重现错误:

create_engine('sqlite://', echo='banana')

结果

Traceback (most recent call last):
   ...
KeyError: 'banana'

猜想,问题在于

SQLALCHEMY_ECHO = environ.get('SQLALCHEMY_ECHO')

不认为环境变量总是字符串。这样的事情可能会更好:

SQLALCHEMY_ECHO = environ.get('SQLALCHEMY_ECHO') in ('1', 'True')

因为这将导致分配一个布尔值。

【讨论】:

以上是关于create_engine 中的烧瓶 SQLAlchemy KeyError 'False'的主要内容,如果未能解决你的问题,请参考以下文章

有没有一种简单的方法可以让烧瓶中的会话超时?

烧瓶中的多用户身份验证

烧瓶 SSL 证书中的 OIDC SSO 验证失败

如何循环浏览烧瓶/python中的表单?

如何从烧瓶中的“ImmutableMultiDict”获取数据

从烧瓶中的 PostgreSQL 函数提交事务