I'm trying to write a module that is (somewhat) database independent. I want to define my peewee models and then connect to the database at runtime using the init
method of the database object.
When I pass a Sqlite connection string this works as expected, e.g.
>>> app.db.init('sqlite://mydb.sqlite')
Connects to the database and everything works as expected. But when I try the same with a postgres connection string I get an error;
>>> app.db.init('postgresql://username:password@localhost/mydb')
...
peewee.OperationalError: FATAL: database "postgresql://username:password@localhost/mydb" does not exist
I can get the init
method to connect if I use separate parameters;
>>> app.db.init('mydb', username='username', password='password')
But this doesn't translate well between different database backends.
Can anyone point me in the right direction of getting init
to work with connection URIs?
After some interaction with the Peewee author it would seem that the answer is to use the Proxy
object - http://docs.peewee-orm.com/en/latest/peewee/database.html#dynamically-defining-a-database
in my models module I do;
database_proxy = pw.Proxy()
...
class Blah(pw.Model):
column_one = pw.CharField()
class Meta:
database = database_proxy
Then to connect at run time I do;
>>> from playhouse.db_url import connect
>>> import models
>>> db = connect('postgresql://username:password@localhost/mydb')
>>> models.database_proxy.initialize(db)
Then I can interact with my model objects normally. This way I can switch between different database backends and just have a connection URL string in my application config to switch between them.