Ejemplo n.º 1
0
    def preview(self, tables: Optional[TableInfo]) -> PreviewResult:
        # Preview data in tables mounted by this FDW / data source

        # Local import here since this data source gets imported by the commandline entry point
        from splitgraph.core.common import get_temporary_table_id

        tmp_schema = get_temporary_table_id()
        try:
            # Seed the result with the tables that failed to mount
            result = PreviewResult({
                e.table_name: e
                for e in self.mount(tmp_schema, tables=tables) or []
            })

            # Commit so that errors don't cancel the mount
            self.engine.commit()
            for t in self.engine.get_all_tables(tmp_schema):
                if t in result:
                    continue
                try:
                    result[t] = self._preview_table(tmp_schema, t)
                except psycopg2.DatabaseError as e:
                    logging.warning("Could not preview data for table %s",
                                    t,
                                    exc_info=e)
                    result[t] = MountError(table_name=t,
                                           error=get_exception_name(e),
                                           error_text=str(e).strip())
            return result
        finally:
            self.engine.rollback()
            self.engine.delete_schema(tmp_schema)
            self.engine.commit()
Ejemplo n.º 2
0
    def introspect(self) -> IntrospectionResult:
        # Ability to override introspection by e.g. contacting the remote database without having
        # to mount the actual table. By default, just call out into mount()

        # Local import here since this data source gets imported by the commandline entry point
        from splitgraph.core.common import get_temporary_table_id
        import jsonschema

        tmp_schema = get_temporary_table_id()
        try:
            mount_errors = self.mount(tmp_schema) or []

            table_options = dict(self._get_foreign_table_options(tmp_schema))

            # Sanity check for adapters: validate the foreign table options that we get back
            # to make sure they're still appropriate.
            for v in table_options.values():
                jsonschema.validate(v, self.table_params_schema)

            result = IntrospectionResult({
                t: (
                    self.engine.get_full_table_schema(tmp_schema, t),
                    cast(TableParams, table_options.get(t, {})),
                )
                for t in self.engine.get_all_tables(tmp_schema)
            })

            # Add errors to the result as well
            for error in mount_errors:
                result[error.table_name] = error
            return result
        finally:
            self.engine.rollback()
            self.engine.delete_schema(tmp_schema)
            self.engine.commit()
Ejemplo n.º 3
0
    def _create_staging_table(self) -> str:
        staging_table = get_temporary_table_id()

        logging.debug("Using staging table %s", staging_table)
        self.repository.object_engine.create_table(
            schema=SPLITGRAPH_META_SCHEMA,
            table=staging_table,
            schema_spec=self.table_schema,
            unlogged=True,
        )
        return staging_table
Ejemplo n.º 4
0
    def _load(self, schema: str, tables: Optional[TableInfo] = None):
        from splitgraph.core.common import get_temporary_table_id

        tmp_schema = get_temporary_table_id()
        try:
            self.mount(tmp_schema, tables=tables)
            self.engine.commit()

            for t in self.engine.get_all_tables(tmp_schema):
                try:
                    self.engine.copy_table(tmp_schema, t, schema, t)
                    self.engine.commit()
                except psycopg2.DatabaseError as e:
                    logging.warning("Error ingesting table %s", t, exc_info=e)
        finally:
            self.engine.rollback()
            self.engine.delete_schema(tmp_schema)
            self.engine.commit()