Issue: db.connect() resets everything for in-memory sqlite
Author: hasenj
State: closed
Created: 2013-05-13 08:47:39

This is problematic for unit tests.

I usually have something like:

``` python
@app.before_request
def before_request():
    db.connect()
```

because mysql connection dies out after a while and needs to be renewed all the time.

I also have `db.connect()` for the code the initializes the db and creates tables

But if the db is `Sqlite(':memory:')`, then db.connect() resets it, clears it out; all the data that's been written is erased. Tables don't exist anymore.

Typical pattern in unit testing:
- setup the app with `app.testing = True`
- setup the db to use sqlite's in-memory db
- initialize db (create tables, etc)
- make requests

Requests will fail because `db.connect()` erases all the tables.

Also, worse, in my case I have an unorthodox setup where I have several models spread out across several python modules, each module has its own `db_init()` function which calls `db.connect()` at the top.

My workaround is to use a function call `db_connect()` instead, and make it no-op in testing:

``` python
def db_connect():
    db.connect()

if app.testing:
    # calling db.connect() on an in-memory sqlite database
    # resets everything!
    def db_connect():
        pass
```

But I think peewee should do this itself. I think `db.connect()` should be a no-op for sqlite's in-memory db.


The logic to open and close connections to the database does exactly that -- opens or closes a connection.  That is a library operation and one that will not change or be special-cased.  If in your application's request setup/teardown you are opening and closing connections, but would like to no-op while testing with an in-memory db, that seems to me like an application operation.  It also sounds like your solution is clean, obvious and works well.

Let me know if I'm not fully understanding the issue.


> Let me know if I'm not fully understanding the issue.

Hm, well perhaps I'm the one not understanding the issue.

I was expecting `db.connect` to _renew_ connection if it was lost/gone, but not really do anything if the connection is already active. With sqlite's in-memory db, the 'connection' so to speak is probably already active (I'm not sure if I really understand what a connection actually means in this case), hence I wasn't expecting it to restart anything.


@hasenj -- `connect` will explicitly open a connection.  If you want to check the state, call `db.is_closed`.  Sqlite's in-memory database is unusual in that all data is stored per-connection, so if you want to use it you have to be careful w/your connection handling.  I think that falls more under the scope of your application than the scope of peewee itself.  Apologies if this was confusing.


Thanks! That clears it up!

> Apologies if this was confusing.

Not at all!


I've just run into this issue.  I'm not explicitly calling connect() anywhere so I can't figure out why it's happening


> I've just run into this issue. I'm not explicitly calling connect() anywhere so I can't figure out why it's happening

A connection is opened the first time a query is run, if a connection is not opened already.