Search code examples
pythonormpeewee

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?


Solution

  • 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.