"""This module provides functionality to enable using PostgreSQL as backend."""frompathlibimportPathfrom..engineimportEnginefrom..jsonimportjsonbimportpsycopgaspgDATA_DIR=(Path(__file__).parent).absolute()# monkey patch psycopg cursor to add executescript method like sqlitepg.Cursor.executescript=pg.Cursor.execute
[docs]classPostgresEngine(Engine):def__init__(self,config):# make a copy of the config so we can change itconfig=dict(config)# dbpath, engine are not a valid postgres connection optionconfig.pop("dbpath",None)config.pop("engine")# pop schema and put as search pathif"schema"inconfig:schema=config.pop("schema")self.schema=schemaconfig["options"]=f"--search_path={schema}"# the finished DSNself._dsn=" ".join(f"{k}={pg.sql.quote(v)}"fork,vinconfig.items())self._oid_mapping={}
[docs]defmap_type(self,client,typ):ifnotself._oid_mapping:withclient.cursor()ascur:# get oid mappingcur.execute("SELECT oid, typname FROM pg_type;")foroid,typenameincur.fetchall():self._oid_mapping[oid]=typenamedumper=pg.adapters.get_dumper(typ,pg.adapt.PyFormat.AUTO)ifnotdumperornotdumper.oid:raiseValueError(f"cannot detect postgres type for {typ!r}")returnself._oid_mapping[dumper.oid]