Connection Management
To open a connection to a database, use the Database.connect()
method:
>>> db = SqliteDatabase(':memory:') # In-memory SQLite database.
>>> db.connect()
True
If we try to call connect()
on an already-open database, we get a OperationalError
:
>>> db.connect()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/charles/pypath/peewee.py", line 2390, in connect
raise OperationalError('Connection already opened.')
peewee.OperationalError: Connection already opened.
To prevent this exception from being raised, we can call connect()
with an additional argument, reuse_if_open
:
>>> db.close() # Close connection.
True
>>> db.connect()
True
>>> db.connect(reuse_if_open=True)
False
Note that the call to connect()
returns False
if the database connection was already open.
To close a connection, use the Database.close()
method:
>>> db.close()
True
Calling close()
on an already-closed connection will not result in an exception, but will return False
:
>>> db.connect() # Open connection.
True
>>> db.close() # Close connection.
True
>>> db.close() # Connection already closed, returns False.
False
You can test whether the database is closed using the Database.is_closed()
method:
>>> db.is_closed()
True
Using autoconnect
It is not necessary to explicitly connect to the database before using it if the database is initialized with autoconnect=True
(the default). Managing connections explicitly is considered a best practice, therefore you may consider disabling the autoconnect
behavior.
It is very helpful to be explicit about your connection lifetimes. If the connection fails, for instance, the exception will be caught when the connection is being opened, rather than some arbitrary time later when a query is executed. Furthermore, if using a connection pool, it is necessary to call connect()
and close()
to ensure connections are recycled properly.
For the best guarantee of correctness, disable autoconnect
:
db = PostgresqlDatabase('my_app', user='postgres', autoconnect=False)
Thread Safety
Peewee keeps track of the connection state using thread-local storage, making the Peewee Database
object safe to use with multiple threads. Each thread will have it’s own connection, and as a result any given thread will only have a single connection open at a given time.
Context managers
The database object itself can be used as a context-manager, which opens a connection for the duration of the wrapped block of code. Additionally, a transaction is opened at the start of the wrapped block and committed before the connection is closed (unless an error occurs, in which case the transaction is rolled back).
>>> db.is_closed()
True
>>> with db:
... print(db.is_closed()) # db is open inside context manager.
...
False
>>> db.is_closed() # db is closed.
True
If you want to manage transactions separately, you can use the Database.connection_context()
context manager.
>>> with db.connection_context():
... # db connection is open.
... pass
...
>>> db.is_closed() # db connection is closed.
True
The connection_context()
method can also be used as a decorator:
@db.connection_context()
def prepare_database():
# DB connection will be managed by the decorator, which opens
# a connection, calls function, and closes upon returning.
db.create_tables(MODELS) # Create schema.
load_fixture_data(db)
DB-API Connection Object
To obtain a reference to the underlying DB-API 2.0 connection, use the Database.connection()
method. This method will return the currently-open connection object, if one exists, otherwise it will open a new connection.
>>> db.connection()
<sqlite3.Connection object at 0x7f94e9362f10>