Create a table with data
The Python, TypeScript and Rust blocks below illustrate the corresponding input formats; each assumes adb connection already open, as in
Connect to LanceDB. For a complete connection-to-result
program, expand the write workflow. Table names
follow the naming rules.
From list of objects
You can provide a list of objects to create a table. The Python and TypeScript SDKs support lists/arrays of records. The Rust example converts structs to Arrow batches. In Python, pass a list or other batch-like object; a single baredict or single
LanceModel is rejected.
If the table already exists
By default, creating a table fails if its name is already in use. Choose whether to open that table or overwrite it.Open the existing table
Useexist_ok=True in Python or existOk: true in TypeScript to return the
existing table without changing its contents. This is useful for setup code
that may run more than once. Any data supplied to the create call is ignored
when the table already exists.
Inspect the returned table’s schema if your code depends on specific columns
or types. Opening an existing table does not change its schema to match the
data supplied in the create call.
Overwrite the table
Usemode="overwrite" in Python or mode: "overwrite" in TypeScript to replace
the existing table with the supplied data and schema. Choose this only when
you intend to replace its previous contents.
The following Python program demonstrates both choices:
Python
exist_ok / existOk does not append the provided data to an existing table. Use
table.add() for that. If you need to ensure a table exists and
contains specific rows, choose an explicit merge policy. Creating an empty table
and repeatedly appending the same batch does not deduplicate it.From a custom schema
You can define a custom Arrow schema for the table. This is useful when you want to have more control over the column types and metadata.null). If later writes omit a
non-nullable column, or provide actual nulls for it, ingestion fails; nullable columns can be
omitted or written with null values. Without an explicit schema, Python infers list-like vector
values as fixed-size float32 vector fields from the observed dimension. For images, audio, video, or
other binary columns whose payloads should load on demand, declare a blob column in the schema.
For Python ingestion, malformed vectors fail by default (on_bad_vectors="error"). This includes
vectors with incorrect sizes, NaNs, or null components, including pandas NaNs converted to Arrow
nulls. Use "drop" to remove affected rows, or "null" to replace affected vectors with nulls.
Use "fill" to replace NaN or null components with fill_value while preserving valid components.
This also pads short vectors with fill_value and truncates long vectors to the expected dimension.
From an Arrow Table
You can also create LanceDB tables directly from Arrow tables. Rust uses an ArrowRecordBatchReader for the same Arrow-native ingest flow.
From a Pandas DataFrame
Python OnlyData is converted to Arrow before being written to disk. For maximum control over how data is saved, either provide the PyArrow schema to convert to or else provide a PyArrow Table directly.
The
vector column needs to be a Vector (defined as pyarrow.FixedSizeList) type.From a Polars DataFrame
Python Only Pass a Polars DataFrame as input. Installpolars for this example; the
conversion preserves the table structure through Arrow.
From Pydantic Models
Python Only When you create an empty table without data, you must specify the table schema. LanceDB supports creating tables by specifying a PyArrow schema or a specialized Pydantic model calledLanceModel.
For example, the following Content model specifies a table with 5 columns:
movie_id, vector, genres, title, and imdb_id. When you create a table, you can
pass the class as the value of the schema parameter to create_table.
The vector column is a Vector type, which is a specialized Pydantic type that
can be configured with the vector dimensions. It is also important to note that
LanceDB only understands subclasses of lancedb.pydantic.LanceModel
(which itself derives from pydantic.BaseModel).
Nested schemas
Sometimes your data model may contain nested objects. For example, you may want to store the document string and the document source name as a nested Document object:Validators
BecauseLanceModel inherits from Pydantic’s BaseModel, you can combine them with Pydantic’s
field validators. The example
below shows how to add a validator to ensure that only valid timezone-aware datetime objects are used
for a created_at field.
ValidationError for the timestamp with a different
timezone. A validator runs when the Pydantic model is constructed; declaring a
model as the table schema does not make every later write run that validator.
Datasets too large to pass to
create_table at once are covered separately;
see Insert data for batches, file-backed
input and write parallelism.Create empty table
You can create an empty table for scenarios where you want to add data to the table later. An example would be when you want to collect data from a stream/external file and then add it to a table in batches. An empty table can be initialized via an Arrow schema.LanceModel, a Pydantic model class
provided by lancedb.pydantic. Its Vector type declares a fixed vector dimension.
Open an existing table
You can open an existing table by specifying the name of the table to theopen_table / openTable method.
If you forget the name of your table, you can always get a listing of all table names.
Drop a table
Use thedrop_table() method on the database to remove a table.
ignore_missing=True to suppress it. A deployment may report
success instead, depending on how it stores its catalog, so do not rely on the
error to tell you a table was missing. Python’s deployment connection does not
take ignore_missing.
Complete write workflow
Complete examples: create, append, update, upsert and delete
Complete examples: create, append, update, upsert and delete
Each program creates a temporary local database, performs the five operations,
prints the result, and removes its temporary data when finished.After the operations, Alice has 10 logins, Bobby has 21, and Charlie has 6.
Dana is selected for deletion and is absent from the final result.
- Python: install
lancedb, save the code asingestion.py, and runpython ingestion.py. - TypeScript: install
@lancedb/lancedb, save the code asingestion.mts, and runnode ingestion.mtswith Node.js 22.18 or later. - Rust: download the complete Rust project,
extract it, and run
cargo run --locked. It includessrc/main.rs, the Cargo manifest and a lockfile for the example’s dependencies. The code is shown below.