Skip to main content

Import Data (SDK)

This guide helps you learn how to use our SDKs to import data into a collection with the bulk-writer and bulk-import APIs.

Alternatively, you can also refer to our fast-track end-to-end course which covers both data preparations and data import to Zilliz Cloud collections.

Notes

Zilliz Cloud now allows you to import data from any object storage service to any Zilliz Cloud cluster, regardless of the cloud provider hosting the clusters. For instance, you can import data from an AWS S3 bucket to a Zilliz Cloud cluster deployed on GCP.

You are advised to use a bucket or a blob container from the same provider and in the same region as the target cluster to ensure a low-latency, stable experience.

Install dependencies​

Run the following command in your terminal to install pymilvus and minio or upgrade them to the latest version.

shell
python3 -m pip install --upgrade pymilvus minio

Check prepared data​

Once you have prepared your data using the BulkWriter tool and got the path to the prepared files. You are ready to import them to a Zilliz Cloud collection. To check whether they are ready, do as follows:

python
from minio import Minio
from pymilvus import MilvusClient, DataType
from pymilvus.bulk_writer import bulk_import
import json
from pymilvus.bulk_writer import get_import_progress
from pymilvus.bulk_writer import list_import_jobs

# Third-party constants
ACCESS_KEY = "YOUR_ACCESS_KEY"
SECRET_KEY = "YOUR_SECRET_KEY"
BUCKET_NAME = "YOUR_BUCKET_NAME"
REMOTE_PATH = "YOUR_REMOTE_PATH"

client = Minio(
endpoint="storage.googleapis.com", # use 's3.amazonaws.com' for AWS S3
access_key=ACCESS_KEY,
secret_key=SECRET_KEY,
secure=True
)

objects = client.list_objects(
bucket_name=BUCKET_NAME,
prefix=REMOTE_PATH,
recursive=True
)

print([obj.object_name for obj in objects])

# Output
#
# [
# "folder/1/claps.npy",
# "folder/1/id.npy",
# "folder/1/link.npy",
# "folder/1/publication.npy",
# "folder/1/reading_time.npy",
# "folder/1/responses.npy",
# "folder/1/title.npy",
# "folder/1/vector.npy"
# ]

StructArray fields in source files​

A StructArray field is carried differently by each source file format. The import reader expects one of the following shapes:

FormatStructArray field shape
JSON, JSONLThe field value is a list of objects, one per Struct element, keyed by subfield name: "chunks": [{"text": "...", "section": "index", "emb": [0.1, 0.2]}, ...].
CSVThe cell holds the same JSON text as the JSON format. The nullkey configured for the import job or a JSON null marks a null StructArray value.
ParquetOne column per StructArray field with the type list<struct<...>>, one struct child per subfield. A scalar subfield is a scalar child, a vector subfield is a list of its element type, such as list<float32>, and an array subfield is a list<T> child.
NumPyNot supported. NumPy files hold one file per top-level field and have no representation for a StructArray field. Use JSON, CSV, or Parquet files for collections that have a StructArray field.

The following rules apply to StructArray values in all supported formats:

  • Use subfield names inside each Struct element, not paths such as chunks[text]. Flat columns or keys named chunks[text] are rejected.

  • A Struct element itself cannot be null, such as [null, {...}]. A whole StructArray value can be null only when the StructArray field is nullable.

  • Keys or Parquet children that are not subfields of the collection, including dropped subfields, are ignored.

  • A missing key or a null value for an element-nullable subfield imports as a null value for that Struct element, so files written before a subfield was added import without it. A null anywhere else fails the import. For an array subfield, null is a null inner array, and null inside the inner array is a null inner value when the subfield allows it.

  • Binlog import, such as a backup restore, and snapshot-source import are rejected for collections that have element-nullable subfields or scalar array subfields.

pymilvus BulkWriter supports the StructArray shapes above in every supported format, including element-nullable subfields and nullable StructArray values. Use the same row shapes in the writer's add_row() calls.

For the schema-side limits, see StructArray Limits.

Import data​

Once your data and collection are ready, you can import your data into a specific collection via an external storage, such as an object storage bucket and a block storage blob container.

Import data​

If you prefer to import data via external storage, do as follows:

python
# Bulk-import your data from the prepared data files
CLOUD_API_ENDPOINT = "https://api.cloud.zilliz.com"
CLUSTER_ID = "inxx-xxxxxxxxxxxxxxx"
API_KEY = ""
STORAGE_URL = ""
ACCESS_KEY = ""
SECRET_KEY = ""

res = bulk_import(
api_key=API_KEY,
url=CLOUD_API_ENDPOINT,
cluster_id=CLUSTER_ID,
collection_name="medium_articles",
object_url=STORAGE_URL,
access_key=ACCESS_KEY,
secret_key=SECRET_KEY
)

print(res.json())

# Output
#
# {
# "code": 0,
# "data": {
# "jobId": "9d0bc230-6b99-4739-a872-0b91cfe2515a"
# }
# }
Notes

For successful data import, ensure the target collection has less than 10,000 running or pending import jobs.

Check import progress​

You can check the progress of a specified bulk-import job.

python
## Zilliz Cloud constants
CLOUD_API_ENDPOINT = "https://api.cloud.zilliz.com"
CLUSTER_ID = "inxx-xxxxxxxxxxxxxxx"
API_KEY = ""

# Get bulk-insert job progress
resp = get_import_progress(
api_key=API_KEY,
url=CLOUD_API_ENDPOINT,
cluster_id=CLUSTER_ID,
job_id="job-01fa0e5d42cjxudhpuehyp",
)

print(json.dumps(resp.json(), indent=4))

List all import jobs​

If you also want to know about all bulk-import tasks, you can call the list-import-jobs API as follows:

python
## Zilliz Cloud constants
CLOUD_API_ENDPOINT = "https://api.cloud.zilliz.com"
CLUSTER_ID = "inxx-xxxxxxxxxxxxxxx"
API_KEY = ""

# List bulk-insert jobs
resp = list_import_jobs(
api_key=API_KEY,
url=CLOUD_API_ENDPOINT,
cluster_id=CLUSTER_ID
)

print(json.dumps(resp.json(), indent=4))