0

I have a flask app that connects with mysql using sqlalchemy. A strange error happens on DB query.

`Traceback (most recent call last): File "/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/sqlalchemy/util/_collections.py", line 1008, in call return self.registry[key] KeyError: <greenlet.greenlet object at 0x7f22a0936a90 (otid=0x7f22a08ef100) current active started main>

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "/home/Desktop/work/nesting-app/server/users/routes.py", line 28, in register_new_user if form.validate_on_submit(): File "/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/flask_wtf/form.py", line 100, in validate_on_submit return self.is_submitted() and self.validate() File "/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/wtforms/form.py", line 318, in validate return super(Form, self).validate(extra) File "/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/wtforms/form.py", line 150, in validate if not field.validate(self, extra): File "/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/wtforms/fields/core.py", line 226, in validate stop_validation = self._run_validation_chain(form, chain) File "/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/wtforms/fields/core.py", line 246, in _run_validation_chain validator(form, self) File "/home/Desktop/work/nesting-app/server/users/forms.py", line 43, in validate_email user = User.query.filter_by(email=email.data).first() File "/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/flask_sqlalchemy/init.py", line 552, in get return type.query_class(mapper, session=self.sa.session()) File "/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/sqlalchemy/orm/scoping.py", line 47, in call sess = self.registry() File "/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/sqlalchemy/util/collections.py", line 1010, in call return self.registry.setdefault(key, self.createfunc()) File "/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/sqlalchemy/orm/session.py", line 4171, in call return self.class(**local_kw) File "/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/flask_sqlalchemy/init.py", line 176, in init bind = options.pop('bind', None) or db.engine File "/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/flask_sqlalchemy/init.py", line 998, in engine return self.get_engine() File "/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/flask_sqlalchemy/init.py", line 1017, in get_engine return connector.get_engine() File "/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/flask_sqlalchemy/init.py", line 594, in get_engine self._engine = rv = self._sa.create_engine(sa_url, options) File "/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/flask_sqlalchemy/init.py", line 1027, in 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", line 298, in warned return fn(*args, **kwargs) File "/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/sqlalchemy/engine/create.py", line 661, in 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", line 2758, in init self.echo = echo File "/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/sqlalchemy/log.py", line 225, in set instance_logger(instance, echoflag=value) File "/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/sqlalchemy/log.py", line 202, in instance_logger logger = InstanceLogger(echoflag, name) File "/home/Desktop/work/nesting-app/env/lib/python3.8/site-packages/sqlalchemy/log.py", line 103, in init if self._echo_map[echo] <= logging.INFO and not self.logger.handlers: KeyError: 'False' `

Here is the 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:[email protected]: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')

Here is the 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)

I have tried with different connection strings:

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:[email protected]:3306/dbname

Thank you for any help.

1 Answer 1

0

The echo flag for SQLAlchemy's create_engine function accepts a limited set of values: None, False, True, "debug" (source).

The traceback shows that the string "False" is being passed: KeyError: 'False'. In fact, the error can be reproduced by passing any string (except "debug") as the value of create_engine's echo flag:

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

results in

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

At a guess, the problem is that

SQLALCHEMY_ECHO = environ.get('SQLALCHEMY_ECHO')

does not consider that environment variables are always strings. Something like this might be better:

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

as it will result in a boolean value being assigned.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.