Database __init__ appears to catch wrong exception type for Postgres when tables already exist

database
bug
(Philipp Dowling) #1

The Database object’s __init__ looks like this:

class Database(object):
    def __init__(self, db, display_id="custom", display_name=None):
        """Initialize a database.

        db: A database object that can be initialized by peewee.
        display_id (unicode): Database ID used for logging, e.g. 'sqlite'.
        display_name (unicode): Database name used for logging, e.g. 'SQLite'.
        RETURNS (Database): The initialized database.
        """
        DB_PROXY.initialize(db)
        self.db_id = display_id
        self.db_name = display_name or get_display_name(db)
        log("DB: Initialising database {}".format(self.db_name))
        try:
            DB_PROXY.create_tables(DB_TABLES, safe=True)
        except orm.OperationalError:
            pass
        self.db = DB_PROXY

Basically, when Prodigy’s required tables already exist, it should raise an OperationalError but fail quietly since this is not actually a problem. I found that when connecting to a Postgres backend, in fact a psycopg2.ProgrammingError is being raised and the __init__ call fails. It’s not too hard to work around this by just monkey-patching the method, but you may want to investigate why exactly this happens (I am not sure if this is somehow unique to my system or a general problem).
Also: I am connecting to the db with the following underlying playhouse call:

_db = PostgresqlExtDatabase(
        params["database"],
        user=params["user"],
        password=params["password"],
        host=params["host"],
        options='-c search_path="prodigy"'  # use schema to separate data from core app
    )
db = Database(_db)

Pretty normal, except that I am setting a search_path to have prodigy use a different schema than the default one. I don’t know if this would be related at all though.

1 Like