This is the supported list of connectors for Storage Services:
In any other connector, extracting metadata happens automatically. We have different ways to understand the information in the sources and send that to OpenMetadata. However, what happens with generic sources such as S3 buckets, or ADLS containers?
In these systems we can have different types of information:
- Unstructured data, such as images or videos,
- Structured data in single and independent files (which can also be ingested with the Data Lake connector)
- Structured data in partitioned files, e.g.,
Then the question is, how do we know which data in each Container is relevant and which structure does it follow? In order to optimize ingestion costs and make sure we are only bringing in useful metadata, the Storage Services ingestion process follow this approach:
- We list the top-level containers (e.g., S3 buckets), and bring generic insights, such as size and number of objects.
- If there is an
openmetadata.jsonmanifest file present in the bucket root, we will ingest the informed paths as children of the top-level container. Let's see how that works.
Note that the current implementation brings each entry in the
openmetadata.json as a child container of the top-level container. Even if your data path is
s3://bucket/my/deep/table, we will bring
bucket as the top-level container and
my/deep/table as its child.
We are flattening this structure to simplify the navigation.
Our manifest file is defined as a JSON Schema, and can look like this:
Entries: We need to add a list of
entries. Each inner JSON structure will be ingested as a child container of the top-level one. In this case, we will be ingesting 4 children.
Simple Container: The simplest container we can have would be structured, but without partitions. Note that we still need to bring information about:
- dataPath: Where we can find the data. This should be a path relative to the top-level container.
- structureFormat: What is the format of the data we are going to find. This information will be used to read the data.
- separator: Optionally, for delimiter-separated formats such as CSV, you can specify the separator to use when reading the file. If you don't, we will use
,for CSV and
/tfor TSV files.
After ingesting this container, we will bring in the schema of the data in the
Partitioned Container: We can ingest partitioned data without bringing in any further details.
By informing the
isPartitioned field as
true, we'll flag the container as
Partitioned. We will be reading the source files schemas', but won't add any other information.
Single-Partition Container: We can bring partition information by specifying the
partitionColumns. Their definition is based on the JSON Schema definition for table columns. The minimum required information is the
partitionColumns, these values will be added to the schema, on top of the inferred information from the files.
Multiple-Partition Container: We can add multiple columns as partitions.
Note how in the example we even bring our custom
displayName for the column
dataTypeDisplay for its type.
Again, this information will be added on top of the inferred schema from the data files.
You can also manage a single manifest file to centralize the ingestion process for any container. In that case, you will need to add a
containerName entry to the structure above. For example:
You can also keep local manifests in each container, but if possible, we will always try to pick up the global manifest during the ingestion.
We will look for a file named