Internal
Use Db.table to obtain an instance of this class.
Private
Readonly
#commandsPrivate
Readonly
#dbPrivate
Readonly
#httpReadonly
keyspaceThe keyspace that the table resides in.
Readonly
nameThe name of the table. Unique per keyspace.
Backdoor to the HTTP client for if it's absolutely necessary. Which it almost never (if even ever) is.
Performs one of the four available table-alteration operations:
add
(adds columns to the table)drop
(removes columns from the table)addVectorize
(enabled auto-embedding-generation on existing vector columns)dropVectorize
(disables vectorize on existing enabled columns)The options for this operation.
The table with the new schema type.
interface User {
id: UUID,
vector: DataAPIVector,
}
const table = db.table<User>('users');
// Add a column to the table
type NewUser = User & { name: string };
const newTable = await table.alter<NewUser>({
operation: {
add: {
columns: { name: 'text' },
},
},
});
// Drop a column from the table (resets it to how it was originally)
const oldTable = await newTable.alter<User>({
operation: {
drop: {
columns: ['name'],
},
},
});
Table
The alter
operation returns the table itself, with the new schema type.
It is heavily recommended to store the result of the alter
operation in a new variable, as the old table will not have the new schema type.
You should provide the exact new type of the schema, or it'll just default to SomeRow
.
Creates a secondary non-vector index on the table.
The operation blocks until the index is created and ready to use.
See Table.createVectorIndex for creating vector indexes.
text
and ascii
-based indexes have access to a few additional options:
caseSensitive
(default: true
)normalize
(default: true
)ascii
(default: false
)The name of the index
The column to index
Optional
options: CreateTableIndexOptionsOptions for this operation
A promise which resolves once the index is created.
Creates an index on an existing vector column in the table.
The operation blocks until the index is created and ready to use.
See Table.createIndex for creating non-vector indexes.
The name of the index
The vector column to index
Optional
options: CreateTableVectorIndexOptionsOptions for this operation
A promise which resolves once the index is created.
Get the table definition, i.e. it's columns and primary key definition.
The method issues a request to the Data API each time it is invoked, without caching mechanisms; this ensures up-to-date information for usages such as real-time collection validation by the application.
Optional
options: WithTimeout<"tableAdminTimeoutMs">The options for this operation.
The definition of the table.
const definition = await table.definition();
console.log(definition.columns);
A filter to select the row(s) to delete.
Optional
timeout: WithTimeout<"generalMethodTimeoutMs">The timeout for this operation.
A promise which resolves once the operation is completed.
await table.insertOne({ pk: 'abc', ck: 3 });
await table.insertOne({ pk: 'abc', ck: 4 });
await table.deleteMany({ pk: 'abc' });
There are different forms of accepted filters:
partitionSort
columns not providedvoid
The deleteMany
operation, as returned from the Data API, is always { deletedCount: -1 }
, regardless of how many things are actually matched/modified.
In that sense, returning constantly that one type is isomorphic to just returning void
, as both realistically contain the same amount of information (i.e. none)
A filter to select the row to delete.
Optional
timeout: WithTimeout<"generalMethodTimeoutMs">The timeout for this operation.
A promise which resolves once the operation is completed.
await table.insertOne({ pk: 'abc', ck: 3 });
await table.deleteOne({ pk: 'abc', ck: 3 });
The filter must contain an exact primary key to delete just one row.
Attempting to pass an empty filter, filtering by only part of the primary key, or filtering by a non-primary key column will result in an error.
void
The deleteOne
operation, as returned from the Data API, is always { deletedCount: -1 }
, regardless of how many things are actually matched/modified.
In that sense, returning constantly that one type is isomorphic to just returning void
, as both realistically contain the same amount of information (i.e. none)
Optional
options: Omit<DropTableOptions, "keyspace">The options for this operation.
A promise which resolves when the table has been dropped.
const table = await db.table('my_table');
await table.drop();
Once the table is dropped, this object is still technically "usable", but any further operations on it will fail at the Data API level; thus, it's the user's responsibility to make sure that the table object is no longer used.
Use with caution. Wear your safety goggles. Don't say I didn't warn you.
A filter to select the rows to find. If not provided, all rows will be returned.
Optional
options: GenericFindOptions & { The options for this operation.
a FindCursor which can be iterated over.
const cursor = await table.find({ name: 'John Doe' });
const docs = await cursor.toArray();
This overload of Table.find is used for when no projection is provided, and it is safe to assume the returned rows are going to be of type Schema
.
If it can not be inferred that a projection is definitely not provided, the Schema
is forced to be Partial<Schema>
if the user does not provide their own, in order to prevent type errors and ensure the user is aware that the row may not be of the same type as Schema
.
The filter can contain a variety of operators & combinators to select the rows. See TableFilter for much more information.
If the filter is empty, all rows in the table will be returned (up to any provided/implied limit).
If the table has vector search enabled, you can find the most relevant rows by providing a vector in the sort option.
Vector ANN searches cannot return more than a set number of rows, which, at the time of writing, is 1000 items.
await table.insertMany([
{ name: 'John Doe', vector: [.12, .52, .32] },
{ name: 'Jane Doe', vector: [.32, .52, .12] },
{ name: 'Dane Joe', vector: [.52, .32, .12] },
]);
const cursor = table.find({}, {
sort: { vector: [.12, .52, .32] },
});
// Returns 'John Doe'
console.log(await cursor.next());
The sort option can be used to sort the rows returned by the cursor. See Sort for more information.
The DataStax documentation site also contains further information on the available sort operators.
If the sort option is not provided, there is no guarantee as to the order of the rows returned.
When providing a non-vector sort, the Data API will return a smaller number of rows, set to 20 at the time of writing, and stop there. The returned rows are the top results across the whole table according to the requested criterion.
await table.insertMany([
{ name: 'John Doe', age: 1, height: 168 },
{ name: 'John Doe', age: 2, height: 42 },
]);
const cursor = table.find({}, {
sort: { age: 1, height: -1 },
});
// Returns 'John Doe' (age 2, height 42), 'John Doe' (age 1, height 168)
console.log(await cursor.toArray());
Other available options include skip
, limit
, includeSimilarity
, and includeSortVector
. See TableFindOptions and FindCursor for more information.
If you prefer, you may also set these options using a fluent interface on the FindCursor itself.
// cursor :: FindCursor<string>
const cursor = table.find({})
.sort({ vector: [.12, .52, .32] })
.projection<{ name: string, age: number }>({ name: 1, age: 1 })
.includeSimilarity(true)
.map(doc => `${doc.name} (${doc.age})`);
When not specifying sorting criteria at all (by vector or otherwise), the cursor can scroll through an arbitrary number of rows as the Data API and the client periodically exchange new chunks of rows.
--
It should be noted that the behavior of the cursor in the case rows
have been added/removed after the find
was started depends on database
internals, and it is not guaranteed, nor excluded, that such "real-time"
changes in the data would be picked up by the cursor.
A filter to select the rows to find. If not provided, all rows will be returned.
The options for this operation.
a FindCursor which can be iterated over.
const cursor = await table.find({ name: 'John Doe' });
const docs = await cursor.toArray();
This overload of Table.find is used for when a projection is provided (or at the very least, it can not be inferred that a projection is NOT provided).
In this case, the user must provide an explicit projection type, or the type of the rows will be Partial<Schema>
, to prevent type-mismatches when the schema is strictly provided.
interface User {
name: string,
car: { make: string, model: string },
}
const table = db.table<User>('users');
// Defaulting to `Partial<User>` when projection is not provided
const cursor = await table.find({}, {
projection: { car: 1 },
});
// next :: { car?: { make?: string, model?: string } }
const next = await cursor.next();
console.log(next.car?.make);
// Explicitly providing the projection type
const cursor = await table.find<Pick<User, 'car'>>({}, {
projection: { car: 1 },
});
// next :: { car: { make: string, model: string } }
const next = await cursor.next();
console.log(next.car.make);
// Projection existence can not be inferred
function mkFind(projection?: Projection) {
return table.find({}, { projection });
}
// next :: Partial<User>
const next = await mkFind({ car: 1 }).next();
console.log(next.car?.make);
The filter can contain a variety of operators & combinators to select the rows. See TableFilter for much more information.
If the filter is empty, all rows in the table will be returned (up to any provided/implied limit).
If the table has vector search enabled, you can find the most relevant rows by providing a vector in the sort option.
Vector ANN searches cannot return more than a set number of rows, which, at the time of writing, is 1000 items.
await table.insertMany([
{ name: 'John Doe', vector: [.12, .52, .32] },
{ name: 'Jane Doe', vector: [.32, .52, .12] },
{ name: 'Dane Joe', vector: [.52, .32, .12] },
]);
const cursor = table.find({}, {
sort: { vector: [.12, .52, .32] },
});
// Returns 'John Doe'
console.log(await cursor.next());
The sort option can be used to sort the rows returned by the cursor. See Sort for more information.
The DataStax documentation site also contains further information on the available sort operators.
If the sort option is not provided, there is no guarantee as to the order of the rows returned.
When providing a non-vector sort, the Data API will return a smaller number of rows, set to 20 at the time of writing, and stop there. The returned rows are the top results across the whole table according to the requested criterion.
await table.insertMany([
{ name: 'John Doe', age: 1, height: 168 },
{ name: 'John Doe', age: 2, height: 42 },
]);
const cursor = table.find({}, {
sort: { age: 1, height: -1 },
});
// Returns 'John Doe' (age 2, height 42), 'John Doe' (age 1, height 168)
console.log(await cursor.toArray());
Other available options include skip
, limit
, includeSimilarity
, and includeSortVector
. See TableFindOptions and FindCursor for more information.
If you prefer, you may also set these options using a fluent interface on the FindCursor itself.
// cursor :: FindCursor<string>
const cursor = table.find({})
.sort({ vector: [.12, .52, .32] })
.projection<{ name: string, age: number }>({ name: 1, age: 1 })
.includeSimilarity(true)
.map(doc => `${doc.name} (${doc.age})`);
When not specifying sorting criteria at all (by vector or otherwise), the cursor can scroll through an arbitrary number of rows as the Data API and the client periodically exchange new chunks of rows.
--
It should be noted that the behavior of the cursor in the case rows
have been added/removed after the find
was started depends on database
internals, and it is not guaranteed, nor excluded, that such "real-time"
changes in the data would be picked up by the cursor.
A filter to select the rows to find. If not provided, all rows will be returned.
Optional
options: GenericFindOneOptions & { The options for this operation.
A row matching the criterion, or null
if no such row exists.
const doc = await table.findOne({ name: 'John Doe' });
This overload of Table.findOne is used for when no projection is provided, and it is safe to assume the returned row is going to be of type Schema
.
If it can not be inferred that a projection is definitely not provided, the Schema
is forced to be Partial<Schema>
if the user does not provide their own, in order to prevent type errors and ensure the user is aware that the row may not be of the same type as Schema
.
The filter can contain a variety of operators & combinators to select the row. See TableFilter for much more information.
If the filter is empty, and no Sort is present, it's undefined as to which row is selected.
If the table has vector search enabled, you can find the most relevant row by providing a vector in the sort option.
await table.insertMany([
{ name: 'John Doe', vector: [.12, .52, .32] },
{ name: 'Jane Doe', vector: [.32, .52, .12] },
{ name: 'Dane Joe', vector: [.52, .32, .12] },
]);
const doc = table.findOne({}, {
sort: { vector: [.12, .52, .32] },
});
// 'John Doe'
console.log(doc.name);
The sort option can be used to pick the most relevant row. See Sort for more information.
The DataStax documentation site also contains further information on the available sort operators.
If the sort option is not provided, there is no guarantee as to which of the rows which matches the filter is returned.
await table.insertMany([
{ name: 'John Doe', age: 1, height: 168 },
{ name: 'John Doe', age: 2, height: 42 },
]);
const doc = table.findOne({}, {
sort: { age: 1, height: -1 },
});
// 'John Doe' (age 2, height 42)
console.log(doc.name);
Other available options include includeSimilarity
. See TableFindOneOptions for more information.
If you want to get skip
or includeSortVector
as well, use Table.find with a limit: 1
instead.
const doc = await cursor.findOne({}, {
sort: { vector: [.12, .52, .32] },
includeSimilarity: true,
});
A filter to select the rows to find. If not provided, all rows will be returned.
The options for this operation.
A row matching the criterion, or null
if no such row exists.
const doc = await table.findOne({ name: 'John Doe' });
This overload of Table.findOne is used for when a projection is provided (or at the very least, it can not be inferred that a projection is NOT provided).
In this case, the user must provide an explicit projection type, or the type of the returned row will be as Partial<Schema>
, to prevent type-mismatches when the schema is strictly provided.
interface User {
name: string,
car: { make: string, model: string },
}
const table = db.table<User>('users');
// Defaulting to `Partial<User>` when projection is not provided
const doc = await table.findOne({}, {
projection: { car: 1 },
});
// doc :: { car?: { make?: string, model?: string } }
console.log(doc.car?.make);
// Explicitly providing the projection type
const doc = await table.findOne<Pick<User, 'car'>>({}, {
projection: { car: 1 },
});
// doc :: { car: { make: string, model: string } }
console.log(doc.car.make);
// Projection existence can not be inferred
function findOne(projection?: Projection) {
return table.findOne({}, { projection });
}
// doc :: Partial<User>
const doc = await findOne({ car: 1 }).next();
console.log(doc.car?.make);
The filter can contain a variety of operators & combinators to select the row. See TableFilter for much more information.
If the filter is empty, and no Sort is present, it's undefined as to which row is selected.
If the table has vector search enabled, you can find the most relevant row by providing a vector in the sort option.
await table.insertMany([
{ name: 'John Doe', vector: [.12, .52, .32] },
{ name: 'Jane Doe', vector: [.32, .52, .12] },
{ name: 'Dane Joe', vector: [.52, .32, .12] },
]);
const doc = table.findOne({}, {
sort: { vector: [.12, .52, .32] },
});
// 'John Doe'
console.log(doc.name);
The sort option can be used to pick the most relevant row. See Sort for more information.
The DataStax documentation site also contains further information on the available sort operators.
If the sort option is not provided, there is no guarantee as to which of the rows which matches the filter is returned.
await table.insertMany([
{ name: 'John Doe', age: 1, height: 168 },
{ name: 'John Doe', age: 2, height: 42 },
]);
const doc = table.findOne({}, {
sort: { age: 1, height: -1 },
});
// 'John Doe' (age 2, height 42)
console.log(doc.name);
Other available options include includeSimilarity
. See TableFindOneOptions for more information.
If you want to get skip
or includeSortVector
as well, use Table.find with a limit: 1
instead.
const doc = await cursor.findOne({}, {
sort: { vector: [.12, .52, .32] },
includeSimilarity: true,
});
The rows to insert.
Optional
options: GenericInsertManyOptionsThe options for this operation.
The primary keys of the inserted rows (and the count)
import { uuid, vector, ... } from '@datastax/astra-db-ts';
await table1.insertMany([
{ id: uuid(4), name: 'John Doe' }, // or UUID.v4()
{ id: uuid(7), name: 'Jane Doe' },
]);
// Insert a row with a vector
// DataAPIVector class enables faster ser/des
await table2.insertMany([
{ name: 'bob', vector: vector([.12, .52, .32]) }, // or new DataAPIVector([...])
{ name: 'alice', vector: vector([.12, .52, .32]), tags: new Set(['cool']) },
], { ordered: true });
NOTE: This function paginates the insertion of rows in chunks to avoid running into insertion limits. This means multiple requests may be made to the server.
This operation is not necessarily atomic. Depending on the amount of inserted rows, and if it's ordered or not, it can keep running (in a blocking manner) for a macroscopic amount of time. In that case, new rows that are inserted from another concurrent process/application may be inserted during the execution of this method call, and if there are duplicate keys, it's not easy to predict which application will win the race.
By default, it inserts rows in chunks of 50 at a time. You can fine-tune the parameter through the chunkSize
option. Note that increasing chunk size won't necessarily increase performance depending on row size. Instead, increasing concurrency may help.
You can set the concurrency
option to control how many network requests are made in parallel on unordered insertions. Defaults to 8
.
const rows = Array.from({ length: 100 }, (_, i) => ({ id: i }));
await table.insertMany(rows, { batchSize: 100 });
When inserting a row with a primary key that already exists, the new row will be merged with the existing row, with the new values taking precedence.
If you want to delete old values, you must explicitly set them to null
(not undefined
).
// Since insertion is ordered, the last unique value for each
// primary key will be the one that remains in the table.
await table.insertMany([
{ id: '123', col1: 'i exist' },
{ id: '123', col1: 'i am new' },
{ id: '123', col2: 'me2' },
], { ordered: true });
await table.findOne({ id: '123' }); // { id: '123', col1: 'i am new', col2: 'me2' }
// Since insertion is unordered, it can not be 100% guaranteed
// which value will remain in the table for each primary key,
// as concurrent insertions may occur.
await table.insertMany([
{ id: '123', col1: null },
{ id: '123', col1: 'hi' },
]);
// coll1 may technically be either 'hi' or null
await table.findOne({ id: '123' }); // { id: '123', col1: ? }
You may set the ordered
option to true
to stop the operation after the first error; otherwise all rows may be parallelized and processed in arbitrary order, improving, perhaps vastly, performance.
Setting the ordered
operation disables any parallelization so insertions truly are stopped after the very first error.
Setting ordered
also guarantees the order of upsert behavior, as described above.
The type of the primary key of the table is inferred from the second PKey
type-param of the table.
If not present, it defaults to Partial<RSchema>
to keep the result type consistent.
interface User {
id: string,
name: string,
dob?: DataAPIDate,
}
type UserPKey = Pick<User, 'id'>;
const table = db.table<User, UserPKey>('table');
// res.insertedIds is of type { id: string }[]
const res = await table.insertMany([
{ id: '123', thing: 'Sunrise' },
{ id: '456', thing: 'Miso soup' },
]);
console.log(res.insertedIds[0].id); // '123'
InsertManyError
If some rows can't be inserted, (e.g. they have the wrong data type for a column or lack the primary key), the Data API validation check will fail for those entire specific requests containing the faulty rows.
Depending on concurrency & the ordered
parameter, some rows may still have been inserted.
In such cases, the operation will throw a TableInsertManyError containing the partial result.
If a thrown exception is not due to an insertion error, e.g. a 5xx
error or network error, the operation will throw the underlying error.
In case of an unordered request, if the error was a simple insertion error, the TableInsertManyError will be thrown after every row has been attempted to be inserted. If it was a 5xx
or similar, the error will be thrown immediately.
TableInsertManyError - If the operation fails.
The row to insert.
Optional
timeout: WithTimeout<"generalMethodTimeoutMs">The timeout for this operation.
The primary key of the inserted row.
import { UUID, vector, ... } from '@datastax/astra-db-ts';
// Insert a row with a specific ID
await table.insertOne({ id: 'text-id', name: 'John Doe' });
await table.insertOne({ id: UUID.v7(), name: 'Dane Joe' }); // or uuid(7)
// Insert a row with a vector
// DataAPIVector class enables faster ser/des
const vec = vector([.12, .52, .32]); // or new DataAPIVector([.12, .52, .32])
await table.insertOne({ id: 1, name: 'Jane Doe', vector: vec });
// or if vectorize (auto-embedding-generation) is enabled for the column
await table.insertOne({ id: 1, name: 'Jane Doe', vector: "Hey there!" });
When inserting a row with a primary key that already exists, the new row will be merged with the existing row, with the new values taking precedence.
If you want to delete old values, you must explicitly set them to null
(not undefined
).
await table.insertOne({ id: '123', col1: 'i exist' });
await table.findOne({ id: '123' }); // { id: '123', col1: 'i exist' }
await table.insertOne({ id: '123', col1: 'i am new' });
await table.findOne({ id: '123' }); // { id: '123', col1: 'i am new' }
await table.insertOne({ id: '123', col2: 'me2' });
await table.findOne({ id: '123' }); // { id: '123', col1: 'i am new', col2: 'me2' }
await table.insertOne({ id: '123', col1: null });
await table.findOne({ id: '123' }); // { id: '123', col2: 'me2' }
The type of the primary key of the table is inferred from the second PKey
type-param of the table.
If not present, it defaults to Partial<RSchema>
to keep the result type consistent.
interface User {
id: string,
name: string,
dob?: DataAPIDate,
}
type UserPKey = Pick<User, 'id'>;
const table = db.table<User, UserPKey>('table');
// res.insertedId is of type { id: string }
const res = await table.insertOne({ id: '123', name: 'Alice' });
console.log(res.insertedId.id); // '123'
Lists the index names for this table.
If you want to include the index definitions in the response, set nameOnly
to false
(or omit it completely),
using the other overload.
Options for this operation.
A promise that resolves to an array of index names.
// ['my_vector_index', ...]
console.log(await table.listIndexes({ nameOnly: true }));
Lists the indexes for this table.
If you want to use only the index names, set nameOnly
to true
, using the other overload.
Optional
options: ListIndexOptions & { Options for this operation.
A promise that resolves to an array of index info.
// [{ name: 'm_vector_index', definition: { ... } }, ...]
console.log(await db.listTables());
Updates a single row in the table. Under certain conditions, it may insert or delete a row as well.
A filter to select the row to update.
The update to apply to the selected row.
Optional
timeout: WithTimeout<"generalMethodTimeoutMs">The timeout for this operation.
A promise which resolves once the operation is completed.
await table.insertOne({ key: '123', name: 'Jerry' });
await table.updateOne({ key: '123' }, { $set: { name: 'Geraldine' } });
If the row doesn't exist, and you're $set
-ing at least one row to a non-null value, an upsert will occur.
// No upsert will occur here since only nulls are being set
// (this is equivalent to `{ $unset: { name: '' } }`)
await table.updateOne({ key: '123' }, { $set: { name: null } });
// An upsert will occur here since at least one non-null value is being set
await table.updateOne({ key: '123' }, { $set: { name: 'Eleanor', age: null } });
If the row was only upserted in the first place, and now all (non-primary) rows are set to null (or unset), the row will be deleted.
If the row was inserted on, even if it was upserted first, it will not be deleted.
Note that $set
-ing a row to null
is equivalent to $unset
-ing it. The following example would be the exact same using $unset
s.
// Upserts row { key: '123', name: 'Michael', age: 3 } into the table
await table.updateOne({ key: '123' }, { $set: { name: 'Michael', age: 3 } });
// Sets row to { key: '123', name: 'Michael', age: null }
await table.updateOne({ key: '123' }, { $set: { age: null } });
// Deletes row from the table as all non-primary keys are set to null
await table.updateOne({ key: '123' }, { $set: { name: null } });
The filter must contain an exact primary key to update just one row.
Attempting to pass an empty filter, filtering by only part of the primary key, or filtering by a non-primary key column will result in an error.
Updates may perform either $set
or$unset
operations on the row. ($set
-ing a row to null
is equivalent to $unset
-ing it.)
void
The updateOne
operation, as returned from the Data API, is always { matchedCount: 1, modifiedCount: 1 }
, regardless of how many things are actually matched/modified, and if a row is upserted or not.
In that sense, returning constantly that one type is isomorphic to just returning void
, as both realistically contain the same amount of information (i.e. none)
Overview
Represents the interface to a table in a Data-API-enabled database.
This shouldn't be directly instantiated, but rather created via Db.createTable or Db.table.
Example
Typing & Types
NOTE: For most intents & purposes (unless you're using custom ser/des), you can ignore the (generally negligible) difference between
WSchema
andRSchema
, and treatTable
as if it were typed asTable<Schema, PKey>
.A
Table
is typed asTable<WSchema, PKey, RSchema>
, where:WSchema
is the type of the row as it's written to the table (the "write" schema)PKey
(optional) is the type of the primary key of the table as it's returnedRSchema
is the type of the row as it's read from the table (the "read" schema)WSchema
FoundRow<WSchema>
(see FoundRow)See FoundRow for more info about the differences, but again, for most intents & purposes, you can ignore this, and pretend they were
Custom datatypes
Certain datatypes may be represented as TypeScript classes (some native, some provided by
astra-db-ts
), however.For example:
'map<k, v>'
is represented by a native JSMap<K, V>
'vector'
is represented by anastra-db-ts
providedDataAPIVector
'date'
is represented by anastra-db-ts
providedDataAPIDate
You may also provide your own datatypes by providing some custom serialization logic as well (see later section).
Example
Big numbers disclaimer
When
varint
s ordecimal
s are present in the schema, and when you're serializingbigint
s and BigNumbers, it will automatically enable usage of a bignumber-friendly JSON library which is capable of serializing/deserializing these numbers without loss of precision, but is much slower than the native JSON library (but, realistically, the difference is likely negligible).Typing the key
The primary key of the table should be provided as a second type parameter to
Table
.This is a special type that is used to reconstruct the TS type of the primary key in insert operations. It should be an object with the same keys as the primary key columns, and the same types as the schema. Note that there is no distinction between partition and clustering keys in this type.
Example
db.createTable
type inferenceWhen creating a table through Db.createTable, and not using any custom datatypes (see next session), you can actually use the InferTableSchema & InferTablePrimaryKey utility types to infer the schema of the table from the table creation.
Example
Custom datatypes
You can plug in your own custom datatypes, as well as enable many other features by providing some custom serialization/deserialization logic through the
serdes
option in TableOptions, DbOptions, and/or DataAPIClientOptions.dbOptions.Note however that this is currently not entirely stable, and should be used with caution.
See the official DataStax documentation for more info.
Disclaimer
It is on the user to ensure that the TS type of the
Table
corresponds with the actual CQL table schema, in its TS-deserialized form. Incorrect or dynamic tying could lead to surprising behaviours and easily-preventable errors.See Db.createTable, Db.table, and InferTableSchema for much more information about typing.
See