pallets-eco / flask-session

Server side session extension for Flask
https://flask-session.readthedocs.io
BSD 3-Clause "New" or "Revised" License
507 stars 238 forks source link

An error occurred when create_app was executed twice #75

Closed frapples closed 8 months ago

frapples commented 7 years ago

This is create_app function:

import flask
from flask.ext.session import Session
from .models import db

sess = Session()

def create_app():
    app = flask.Flask(__name__)

    app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///:memory:'
    app.config['SQLALCHEMY_ECHO'] = True

    app.config['SESSION_SQLALCHEMY'] = db
    app.config['SESSION_TYPE'] = 'sqlalchemy'
    sess.init_app(app)
    db.init_app(app)
    with app.app_context():
        db.create_all()

    return app

Then exec this code:

    app1 = create_app()
    app2 = create_app()

An error occurred:

Traceback (most recent call last):
  File "./runserver.py", line 12, in <module>
    main()
  File "./runserver.py", line 8, in main
    app2 = create_app()
  File "/home/computer/code/project/flownotebook/backend/flownotebook/__init__.py", line 18, in create_app
    sess.init_app(app)
  File "/usr/local/lib/python3.5/dist-packages/flask_session/__init__.py", line 61, in init_app
    app.session_interface = self._get_interface(app)
  File "/usr/local/lib/python3.5/dist-packages/flask_session/__init__.py", line 105, in _get_interface
    config['SESSION_PERMANENT'])
  File "/usr/local/lib/python3.5/dist-packages/flask_session/sessions.py", line 478, in __init__
    class Session(self.db.Model):
  File "/usr/local/lib/python3.5/dist-packages/flask_sqlalchemy/__init__.py", line 602, in __init__
    DeclarativeMeta.__init__(self, name, bases, d)
  File "/usr/local/lib/python3.5/dist-packages/sqlalchemy/ext/declarative/api.py", line 64, in __init__
    _as_declarative(cls, classname, cls.__dict__)
  File "/usr/local/lib/python3.5/dist-packages/sqlalchemy/ext/declarative/base.py", line 88, in _as_declarative
    _MapperConfig.setup_mapping(cls, classname, dict_)
  File "/usr/local/lib/python3.5/dist-packages/sqlalchemy/ext/declarative/base.py", line 103, in setup_mapping
    cfg_cls(cls_, classname, dict_)
  File "/usr/local/lib/python3.5/dist-packages/sqlalchemy/ext/declarative/base.py", line 131, in __init__
    self._setup_table()
  File "/usr/local/lib/python3.5/dist-packages/sqlalchemy/ext/declarative/base.py", line 395, in _setup_table
    **table_kw)
  File "/usr/local/lib/python3.5/dist-packages/sqlalchemy/sql/schema.py", line 421, in __new__
    "existing Table object." % key)
sqlalchemy.exc.InvalidRequestError: Table 'sessions' is already defined for this MetaData instance.  Specify 'extend_existing=True' to redefine options and columns on an existing Table object.

If I comment sess.init_app(app), this code works fine.

I guess that the two app instance shared the same database, repeat exec the function create_all(), my own definition of those tables can be created good, but the sessions table by using flask-session can not work in this situation.

scythargon commented 5 years ago

same here. damned flask and his not supported batteries

AllanChain commented 4 years ago

Using app factory for testing. This problem is still there and driving me crazy. Please fix it! (There is already a PR commit https://github.com/fengsp/flask-session/pull/12/commits/1c1f7903184673682bd1d75432c8f455b62393a4)

If modifying db is not graceful:

        for c in self.db.Model._decl_class_registry.values():
            if hasattr(c, '__table__') and c.__table__.fullname == table:
                self.sql_session_model = c
                return

Before defining class Session works for me

ikoide commented 3 years ago

I'd like to update @AllanChain's response which worked wonders for me. It appears since sqlalchemy 1.4 (https://github.com/sqlalchemy/sqlalchemy/issues/6080) _decl_class_registry has become depreciated and replaced with _class_registry.

Lxstr commented 8 months ago

This issuse is now fixed from 0.7.0