andy47
andy47

Reputation: 913

Run time initialisation of peewee database for different database backends

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?

Upvotes: 2

Views: 1741

Answers (2)

andy47
andy47

Reputation: 913

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.

Upvotes: 5

andy47
andy47

Reputation: 913

I think I've worked out a way to do this. It's a bit clunky so if anyone has a better suggestion I'm all ears. I'm creating a connect object and then passing it's attributes to the db.init. Like this

>>> from playhouse.db_url import connect
>>> import models
>>> db = connect('postgresql://username:password@localhost/mydb')
>>> models.db.init(db.database, **db.connect_kwargs)

This seems to work with any valid Peewee backend.

Upvotes: 0

Related Questions