Repository: SuperDuperDB/superduperdb
File: superduperdb/backends/ibis/data_backend.py (Python)

Code before:
        return self.conn.list_tables()

    @staticmethod
    def infer_schema(data: t.Mapping[str, t.Any], identifier: t.Optional[str] = None):
        """Infer a schema from a given data object.

        :param data: The data object
        :param identifier: The identifier for the schema, if None, it will be generated
        :return: The inferred schema
        """
        from superduperdb.misc.auto_schema import infer_schema

        return infer_schema(data, identifier=identifier, ibis=True)

    def auto_create_table_schema(self, db, table_name, documents):
        """Auto create table schema.

        For Ibis, we need to create the table schema before inserting the data.
        The function will infer the schema from the first document and create the table
        if the table does not exist.

        :param db: The datalayer instanace
        :param table_name: The table name
        :param documents: The documents
        """
        try:
            table = db.tables[table_name]
        except FileNotFoundError:
            table = None

        schema = self.infer_schema(documents[0])
        if table is None:
            # Should we need to check all the documents?
            table = Table(identifier=table_name, schema=schema)
            if table.primary_id not in schema.fields:
                table.schema.fields[table.primary_id] = dtype('str')
            logging.info(f"Creating table {table_name} with schema {schema.fields_set}")
            db.apply(table)

        else:
            # Only check the shcema built from auto_schema
            # The schema build from user input should not be checked
            if not table.schema.identifier.startswith('AUTO:'):
                return
            table_schema_fields_set = table.schema.fields_set

            check_schema_fields_set = schema.fields_set
            # the schema of new documents should be a subset of the existing schema
            if not table_schema_fields_set.issuperset(check_schema_fields_set):
                new_fields_set = check_schema_fields_set - table_schema_fields_set
                fields_set_message = tuple([f"{k}:{v}" for k, v in new_fields_set])

Review comment (suggestion):
Shouldn't we `return` here (the `Schema` is already created)? Then you get a run-time error 
if the data inserted don't match the already existing `Schema`.

Code after:

    @staticmethod
    def infer_schema(data: t.Mapping[str, t.Any], identifier: t.Optional[str] = None):
        """Infer a schema from a given data object.

        :param data: The data object
        :param identifier: The identifier for the schema, if None, it will be generated
        :return: The inferred schema
        """
        from superduperdb.misc.auto_schema import infer_schema

        return infer_schema(data, identifier=identifier, ibis=True)

    def auto_create_table_schema(self, db, table_name, documents):
        """Auto create table schema.

        For Ibis, we need to create the table schema before inserting the data.
        The function will infer the schema from the first document and create the table
        if the table does not exist.

        :param db: The datalayer instanace
        :param table_name: The table name
        :param documents: The documents
        """
        try:
            table = db.tables[table_name]
            return table
        except FileNotFoundError:
            logging.info(f"Table {table_name} does not exist, auto creating...")
        # Should we need to check all the documents?
        document = documents[0]
        schema = document.schema or self.infer_schema(document)
        table = Table(identifier=table_name, schema=schema)
        if table.primary_id not in schema.fields:
            table.schema.fields[table.primary_id] = dtype('str')
        logging.info(f"Creating table {table_name} with schema {schema.fields_set}")
        db.apply(table)