Issue: «Connection already open» when trying to get data from session_interface in flask
Author: ak4nv
State: closed
Created: 2018-04-02 03:53:01

Hi!
I'm trying to get session data from table in my custom session interface in Flask and I'm getting the error `Connection already open`.
Here is a code sample
```python
import peewee as pw

from flask import Flask, jsonify
from flask.sessions import SessionInterface, SessionMixin
from werkzeug.datastructures import CallbackDict

from playhouse.flask_utils import FlaskDB
from playhouse.sqlite_ext import JSONField

from datetime import datetime


app = Flask(__name__)
db = FlaskDB(app, 'sqliteext:///test_db.sqlite')


class Session(CallbackDict, SessionMixin):

    def __init__(self, store={}):
        def on_update(self):
            self.modified = True

        self._store = store
        self.modified = False

        CallbackDict.__init__(self, store.get('data', {}), on_update)

    @classmethod
    def find(cls, sid):
        try:
            store = SessionStore.get(sid=sid)
        except SessionStore.DoesNotExist:
            store = {}
        return cls(store)

    def save(self):
        if hasattr(self._store, 'data') and self.modified:
            self._store.data = self
        self._store.save()


class MySI(SessionInterface):
    null_session_class = Session

    def open_session(self, app, request):
        sid = request.cookies.get('sid')
        return Session.find(sid) if sid else None

    def save_session(self, app, session, response):
        if session.modified:
            session.save()


class SessionStore(db.Model):
    sid = pw.CharField(primary_key=True)
    data = JSONField()
    expired = pw.DateTimeField(default=datetime.now)

    class Meta:
        table_name = 'sessions'


app.session_interface = MySI()

@app.route('/')
def main():
    return jsonify(ok=1)

if __name__ == '__main__':
    if not SessionStore.table_exists():
        SessionStore.create_table()
    app.run(debug=True)
```

And try this
```bash
$ curl -b sid=123 localhost:5000
```
With all latest version of flask and peewee
I played around a little bit with versions and I found 2.8.5 peewee version hasn't this issue. It appeared in 2.8.7
Python version is 3.6.4

When you use the `FlaskDB` helper class, it automatically registers two callbacks with Flask:

* before_request() -- open the database connection
* teardown_request() -- close the database connection

My guess is that when the `before_request()` callback fires, it's raising an exception because the database connection was already opened previously...most likely by your session-store implementation.

If you intend to use a database-backed session-store, I'd suggest that you don't use `FlaskDB` and manage the connections yourself (by registering your own `before_request` and `teardown_request` handlers). Or alternatively you could move to a connection-pooled database and handle opening/closing the session-store connections in the session store?

At any rate, I'm not familiar with how flask's session stuff is implemented, there may be hooks or other ways to work around this.

@coleifer year, I understand this. I just wanna say it worked fine on oldier versions of peewee.
BTW, does peewee connect automatically if you execute first query without calling `database.connect()` method?
Just wanna override handlers like this:
```python
def connect_db(self):
    if self.database.is_closed():
        self.database.connect()

def close_db(self, exc):
    if not self.database.is_closed():
        self.database.close()

```

Yea peewee will automatically open a connection in that case.