0

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

`Traceback(最近一次调用最后):文件“/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/sqlalchemy/util/_collections.py”,第1008行,调用 返回自我.registry[key] KeyError: <greenlet.greenlet object at 0x7f22a0936a90 (otid=0x7f22a08ef100) current active started main>

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

回溯(最近一次通话最后):文件“/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 行,在验证中返回 super(Form, self).validate(extra) 文件“/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,链)文件“/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 = User.query.filter_by(email=email.data).first() 文件“/home/Desktop/work /nesting-app/env/lib/python3.8/site-packages/flask_sqlalchemy/init .py”,第 552 行,在获取 返回 type.query_class(mapper, session=self.sa.session()) 文件“/home/Desktop/work/nesting-app/env/lib/python3.8/site- packages/sqlalchemy/orm/scoping.py”,第 47 行,调用 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 行,在调用中 返回 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 文件“/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 返回连接器中。 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 返回 sqlalchemy.create_engine(sa_url, **engine_opts) 文件“”,第 2 行,在 create_engine 文件“/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) 文件“/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 行,在集合中 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 , 名称)文件“/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/sqlalchemy/log.py”,第 103 行,init if self._echo_map[echo] <= logging .INFO 而不是 self.logger.handlers: KeyError: 'False' `

这是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

感谢您的任何帮助。

4

1 回答 1

0

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

回溯显示正在传递字符串 : . 事实上,可以通过传递任何字符串(“debug”除外)作为's标志的值来重现该错误:"False"KeyError: 'False'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')

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

于 2021-10-20T22:40:31.673 回答