Skip to content

Rows

You'll find below all the available methods to interact with the rows of a SeaTable table. In this section, you'll have to deal with the id of the rows. You can find few tips on how to get it in the user manual.

Global structure

Here is the global structure of a row object:

{
  "_id": "Qtf7xPmoRaiFyQPO1aENTjb",
  "_mtime": "2021-03-10T16:19:31.761+00:00",
  "Name": "NewName",
  "Date": "2020-08-01",
  "Content": "111",
  "link": [
            {
              "display_value": "1",
              "row_id": "XzdZfL2oS-aILnhfagTWEg"
            }
          ]
}

Please note the specific format for link-type columns (structure of the array objects for key link):

  • display_value: Value displayed in the cell

  • row_id: id of the linked row in the other table

Get row(s)

getRow / getRowById (deprecated)

Get a table's row via its id rowId.

base.getRow(table: Object/String /* (1)! */, rowId: String);
  1. table: either a table object or the table name

Output Single row object (throws an error if table doesn't exist or if no row with the specified id rowId exists)

Example

const table = base.getTableByName('Table1');
const row = base.getRow(table, "M_lSEOYYTeuKTaHCEOL7nw");
const row = base.getRow('Table1', "M_lSEOYYTeuKTaHCEOL7nw");

getRows

Get all the rows displayed in the view of a table.

base.getRows(table: Object/String, view: Object/String /* (1)! */);
  1. table: either a table object or the table name

    view (required): either a view object or the view name

Output Array of row objects (throws an error if table or view doesn't exist)

Example

const table = base.getTableByName('Table1');
const view = base.getViewByName(table, 'Default View');
const rows = base.getRows(table, view);

rows.forEach((row) => {
    output.text(row._id);
})
const rows = base.getRows('Table1', 'Default View');

query

Use SQL to query a base. SQL queries are the most powerful way access data stored in a base. If your not familiar with SQL syntax, we recommend using first the SQL query plugin. Most SQL syntax is supported, you can check the SQL Reference section of this manual for more information.

await/* (1)! */ base.query(sqlStatement: String);
  1. await is used for asynchronous functions. This is required to ensure that the following operations (or the variable where you store the results) wait for the query's response to arrive before continuing to execute the script

Backticks for table or column names containing or special characters or using reserved words

For SQL queries, you can use numbers, special characters or spaces in the names of your tables and columns. However, you'll have to escape these names with backticks in order for your query to be correctly interpreted, for example SELECT * FROM `My Table`.

Similarly, if some of your of table or column names are the same as SQL function names (for example a date-type column named date), you'll also have to escape them in order for the query interpreter to understand that it's not a function call missing parameters, but rather a table or column name.

Output Array of row objects (single empty object if no row match the request's conditions)

All the examples below are related to a table Bill with the following structure/data:

name price year
Bob 300 2021
Bob 300 2019
Tom 100 2019
Tom 100 2020
Tom 200 2021
Jane 200 2020
Jane 200 2021

Example: Get everything with a wildcard

const data = await base.query('select *  from Bill');/* (1)! */
output.text(data);
  1. * means that you want to get the whole rows data (columns's values and specific row data such as id, etc.)
[
    {
        "name": "Bob",
        "price": 300,
        "year": 2021,
        "_locked": null,
        "_locked_by": null,
        "_archived": false,
        "_creator": "bd26d2b...82ca3fe1178073@auth.local",
        "_ctime": "2025-09-15T10:57:19.106+02:00",
        "_last_modifier": "bd26d2b...82ca3fe1178073@auth.local",
        "_mtime": "2025-09-18T09:52:00+02:00",
        "_id": "W77uzH1cSXu2v2UtqA3xSw"
    },
    {
        "name": "Bob",
        "price": 300,
        "year": 2019,
        "_locked": null,
        "_locked_by": null,
        "_archived": false,
        "_creator": "bd26d2b...82ca3fe1178073@auth.local",
        "_ctime": "2025-09-15T10:57:22.112+02:00",
        "_last_modifier": "bd26d2b...82ca3fe1178073@auth.local",
        "_mtime": "2025-09-18T09:52:00+02:00",
        "_id": "IxONgyDFQxmcDKpZWlQ9XA"
    },
    {
        "name": "Tom",
        "price": 100,
        "year": 2019,
        "_locked": null,
        "_locked_by": null,
        "_archived": false,
        "_creator": "bd26d2b...82ca3fe1178073@auth.local",
        "_ctime": "2025-09-15T10:57:23.4+02:00",
        "_last_modifier": "bd26d2b...82ca3fe1178073@auth.local",
        "_mtime": "2025-09-18T09:52:00+02:00",
        "_id": "K4LBuQ7aSjK9JwN14ITqvA"
    },
    {
        "name": "Tom",
        "price": 100,
        "year": 2020,
        "_locked": null,
        "_locked_by": null,
        "_archived": false,
        "_creator": "bd26d2b...82ca3fe1178073@auth.local",
        "_ctime": "2025-09-18T09:52:00+02:00",
        "_last_modifier": "bd26d2b...82ca3fe1178073@auth.local",
        "_mtime": "2025-09-18T09:52:00+02:00",
        "_id": "EHcQEaxiRzm3Zvq8B33bwQ"
    },
    {
        "name": "Tom",
        "price": 200,
        "year": 2021,
        "_locked": null,
        "_locked_by": null,
        "_archived": false,
        "_creator": "bd26d2b...82ca3fe1178073@auth.local",
        "_ctime": "2025-09-18T09:52:00+02:00",
        "_last_modifier": "bd26d2b...82ca3fe1178073@auth.local",
        "_mtime": "2025-09-18T09:52:00+02:00",
        "_id": "CjaCdBlNRXKkYkm231shqg"
    },
    {
        "name": "Jane",
        "price": 200,
        "year": 2020,
        "_locked": null,
        "_locked_by": null,
        "_archived": false,
        "_creator": "bd26d2b...82ca3fe1178073@auth.local",
        "_ctime": "2025-09-18T09:52:00+02:00",
        "_last_modifier": "bd26d2b...82ca3fe1178073@auth.local",
        "_mtime": "2025-09-18T09:52:00+02:00",
        "_id": "YzmUexIAR7iDWmhKGHgpMw"
    },
    {
        "name": "Jane",
        "price": 200,
        "year": 2021,
        "_locked": null,
        "_locked_by": null,
        "_archived": false,
        "_creator": "bd26d2b...82ca3fe1178073@auth.local",
        "_ctime": "2025-09-18T09:52:00+02:00",
        "_last_modifier": "bd26d2b...82ca3fe1178073@auth.local",
        "_mtime": "2025-09-18T09:52:00+02:00",
        "_id": "HJi7wbUMQIOuIlPaoO9Fbg"
    }
]

Example with WHERE

const data = await base.query('select name, price from Bill where year = 2021');
output.text(data);
[
    {"name":"Bob","price":"300"},
    {"name":"Tom","price":"200"},
    {"name":"Jane","price":"200"}
]
const data = await base.query('select name, price, year from Bill where name = "Bob"');
output.text(data);
[
    {"name":"Bob","price":"300","year":"2021"},
    {"name":"Bob","price":"300","year":"2019"}
]

Example with GROUP BY

const data = await base.query('select name, sum(price) from Bill group by name');
output.text(data);
[
    {'name': 'Bob', 'SUM(price)': 600},
    {'name': 'Tom', 'SUM(price)': 400},
    {'name': 'Jane', 'SUM(price)': 400}
]

Example with DISTINCT

const data = await base.query('select distinct name from Bill');
output.text(data);
[
    {'name': 'Bob'},
    {'name': 'Tom'},
    {'name': 'Jane'}
]

getGroupedRows

Get rows in the grouped view of a table.

base.getGroupedRows(table: Object/String, view: Object/String /* (1)! */);
  1. table: either a table object or the table name

    view (required): either a view object or the view name

Output Array of grouped rows object (see Output example below)

Example

const table = base.getTableByName('Table1');
const view = base.getViewByName(table, 'GroupedView');
const groupViewRows = base.getGroupedRows(table, view);
[
    { /* (1)! */
        "column_name": "date",
        "column_key": "tc2B",
        "cell_value": "2025-09",
        "rows": [], /* (2)! */
        "subgroups": [
        {
            "column_name": "Val2",
            "column_key": "7Q0G",
            "cell_value": 462,
            "rows": [
            {
                "bjcM": 12,
                "0000": "John",
                "7Q0G": 462,
                "tc2B": "2025-09-11",
                "Tm99": "520035",
                "_creator": "aa",
                "_last_modifier": "cc7a1d0fce...b65b99@auth.local",
                "_id": "AGO_2SiiTY61uMr-tTVGvQ",
                "_ctime": "2025-09-11T07:38:23.082+00:00",
                "_mtime": "2025-09-11T09:28:32.204+00:00",
                "mpxK": 0
            },
            {
                "bjcM": 12,
                "0000": "John",
                "7Q0G": 462,
                "tc2B": "2025-09-11",
                "Tm99": "520035",
                "_creator": "aa",
                "_last_modifier": "cc7a1d0fce...b65b99@auth.local",
                "_id": "WTu6o6lxS-ChnamkU1wjuA",
                "_ctime": "2025-09-11T07:39:10.297+00:00",
                "_mtime": "2025-09-11T09:28:32.204+00:00",
                "mpxK": 0
            }
            ],
            "subgroups": [] /* (3)! */
        }
        ]
    },
    {
        "column_name": "date",
        "column_key": "tc2B",
        "cell_value": null,
        "rows": [],
        "subgroups": [
        {
            "column_name": "Val2",
            "column_key": "7Q0G",
            "cell_value": 4,
            "rows": [
            {
                "_id": "GIgxrz8VSzm-aHSbJ6_i4w",
                "_participants": [],
                "_creator": "cc7a1d0fce...b65b99@auth.local",
                "_ctime": "2025-09-03T07:03:57.838+00:00",
                "_last_modifier": "cc7a1d0fce...b65b99@auth.local",
                "_mtime": "2025-09-17T15:31:04.150+00:00",
                "bjcM": 1,
                "0000": "name",
                "7Q0G": 4,
                "plxx": 5676,
                "Tm99": "207110",
                "mpxK": ""
            },
            {
                "_id": "PSfpr9dzRPaKUeIn-3va0w",
                "_participants": [],
                "_creator": "cc7a1d0fce...b65b99@auth.local",
                "_ctime": "2025-09-03T07:03:57.838+00:00",
                "_last_modifier": "cc7a1d0fce...b65b99@auth.local",
                "_mtime": "2025-09-11T09:28:32.204+00:00",
                "bjcM": 0,
                "0000": "zu",
                "7Q0G": 4,
                "plxx": 3872,
                "Tm99": "375528",
                "mpxK": 0
            }
            ],
            "subgroups": []
        },
        {
            "column_name": "Val2",
            "column_key": "7Q0G",
            "cell_value": 9,
            "rows": [
            {
                "_id": "H3djeRnkQdWhKBhEG2cGUw",
                "_participants": [],
                "_creator": "cc7a1d0fce...b65b99@auth.local",
                "_ctime": "2025-09-03T07:03:57.838+00:00",
                "_last_modifier": "cc7a1d0fce...b65b99@auth.local",
                "_mtime": "2025-09-11T09:28:32.204+00:00",
                "bjcM": 3,
                "0000": "a",
                "7Q0G": 9,
                "plxx": 1668,
                "Tm99": "520035",
                "mpxK": 0
            },
            {
                "_id": "ARedNyn8R7CZFmRushZmvQ",
                "_participants": [],
                "_creator": "cc7a1d0fce...b65b99@auth.local",
                "_ctime": "2025-09-03T08:23:03.776+00:00",
                "_last_modifier": "cc7a1d0fce...b65b99@auth.local",
                "_mtime": "2025-09-17T15:31:09.842+00:00",
                "0000": "b",
                "bjcM": "",
                "7Q0G": 9,
                "plxx": 610,
                "Tm99": "211464",
                "mpxK": 0
            },
            {
                "_id": "L4IWGz4hT3qb1_u9bBbvFg",
                "_participants": [],
                "_creator": "cc7a1d0fce...b65b99@auth.local",
                "_ctime": "2025-09-03T14:03:51.524+00:00",
                "_last_modifier": "cc7a1d0fce...b65b99@auth.local",
                "_mtime": "2025-09-17T15:31:08.429+00:00",
                "0000": "name",
                "bjcM": 15,
                "7Q0G": 9,
                "plxx": 565,
                "Tm99": "745764",
                "mpxK": 0
            }
            ],
            "subgroups": []
        }
        ]
    }
]
  1. Grouped rows object containing either rows or subgroups (array of grouped rows objects) in the case of multiple grouping rules

  2. No rows: this grouped rows object only contains subgroups (member of the first grouping rule)

  3. No subgroups: this grouped rows object only contains rows (member of the last grouping rule)

const groupViewRows = base.getGroupedRows('Table1', 'GroupedView');

Add row

appendRow / addRow (deprecated)

Add a row to a table. This row contains the data specified in the object rowData. The row will be empty if rowData is empty or if it contains only keys that don't exist in the table.

base.appendRow(table: Object/String, rowData: Object, viewName: String /* (1)! */)
  1. table: either a table object or the table name

    rowData: object (pairs of key:value, each key being the name of a column), for example:

    {
        'First Name': 'John',
        'Last Name': 'Doe',
        'Invoice amount': 100,
        'Products': ['Office Supplies', 'Computer']
    }
    

Output Single row object (throws an error if table doesn't exist)

Example

const table = base.getTableByName('Table1');
base.appendRow(table, {'Name': 'Alex', 'Age': '18'});
base.appendRow(table, {'Name': 'Alex', 'Age': '18'}, 'Default View');

Update row(s)

updateRow / modifyRow(deprecated)

Modify a row in the table. The updateRowData object (pairs of key:value, each key being the name of a column) need to contain only the data you want to update. To reset a value, specify the key:value pair with an empty string ''.

base.updateRow(table: Object/String, row: Object/String, updateRowData: Object /* (1)! */);
  1. table: either a table object or the table name

    row: either a row object or the row id

Output Nothing (throws an error if table doesn't exist or if no row with the specified id exists)

Example

const table = base.getTableByName('Table1');
const row = base.getRow(table, "M_lSEOYYTeuKTaHCEOL7nw");
base.updateRow(table, row, {'Name': 'new name', 'number': 100});
base.updateRow('Table1', 'U_eTV7mDSmSd-K2P535Wzw', {'Name': 'new name', 'number': 100})

modifyRows

Modify multiple rows in the table at once. updatedRows is an array of updateRowData objects (see above). Please note that rows only accepts an array of row objects (and not of ids).

base.modifyRows(table: Object/String, rows: Array of Object, updatedRows: Array of Object /* (1)! */);
  1. table: either a table object or the table name

    rows: array of row objects only (not row ids)

Output Nothing (throws an error if table doesn't exist or if one row in rows doesn't exists)

Example

const table = base.getTableByName('Table1');
const rows = base.getRows(table, 'Default View');
const selectedColumnName = 'Name';
const selectedRows = [], updatedRows = [];

rows.forEach((row) => {
if (row[selectedColumnName] === 'name') {
    selectedRows.push(row);
    updatedRows.push({[selectedColumnName]: 'name1'});
}
});
base.modifyRows(table, selectedRows, updatedRows);
base.modifyRows('Table1', [base.getRow('Table1','GIgxrz8VSzm-aHSbJ6_i4w'),base.getRow('Table1','PSfpr9dzRPaKUeIn-3va0w')], [{'Name': 'name'},{'Name': 'name'}]);

Delete row

deleteRow / deleteRowById (deprecated)

Delete a row in a table by its id rowId.

base.deleteRow(table: Object/String, rowId: String /* (1)! */);
  1. table: either a table object or the table name

    rowId: the id of the row to delete

Output Nothing (no error if no row with id rowId exists)

Example

const table = base.getTableByName('Table1');
base.deleteRow(table, 'M_lSEOYYTeuKTaHCEOL7nw');
base.deleteRow('Table1', 'M_lSEOYYTeuKTaHCEOL7nw');

Filter

filter

Filters the rows displayed in the view viewName of the table that meet the conditions of the filterExpression (conditional statement), and returns a querySet object. See the filterExpression reference below for more details.

base.filter(tableName: String, viewName: String, filterExpression: String);

Output Single querySet object (see below), the rows array being empty if no row meet the filterExpression conditions

Example

// Filter out rows whose number column is equal to 5, and return a querySet object
const querySet = base.filter('Table1', 'Default View', 'number = 5');
{
    "rows": [ /* (1)! */
        ...
    ],
    "table": { /* (2)! */
        ...
    },
    "parser": {
        ...
    }
}
  1. rows: array of the rows in the view viewName meeting the filterExpression conditions

  2. table: the whole table object

const querySet = base.filter("Table1", "Default View", "age>18"/* (1)! */)
  1. age: column name

    >: operator

    18: parameter

filterExpression reference

filterExpression

The most common operators are available to define the conditional statement of the filterExpression:

Type of operators Available operators
Greater-Less comparisons >=, >, <, <=
Equal-Not equal comparisons =, <> (not equal to)
Arithmetic operators +, -, *, /, ^ (power), % (modulo)
Logical operators and, or

Depending on the data type, there are slight differences in the query method and the format of input statement. Here is a list of the possible operations for each type:

Data structure Column type Format for Greater-Less comparisons Format for Equal-Not equal comparisons Arithmetic operators
String Text, Long Text, URL,Email, Single Select Unsupported String Unsupported
List Multiple Select Unsupported String Unsupported
Number Number Number Number and empty String """" Supported
Date Date, Created time, Last modified time Patterns: YYYY-MM-DD, YYYY-MM-DD hh:mm, YYYY-MM-DD hh:mm:ss Same patterns as greater-less query Unsupported
Boolean Checkbox Unsupported true, false and empty String "", (case-insensitive) Unsupported

Mind the quotes!

For queries involving string-based or date-based columns, you'll have to use double quotes " " to define the filterExpression as you'll need simple quotes ' ' for the strings/dates... Or the opposite: use either "column_name='hello world'" or 'column_name="hello world"'

Here are more examples of the different filter expressions pending of the column type.

String-based Column (Text, Long Text, URL, Email, Single Select columns)

// Equal-unequal query
base.filter('Table1', 'Default View', "column_name='hello world'")
base.filter('Table1', 'Default View', "column_name!=''")


List-based Column (Multiple Select columns)

// Equal-unequal query
base.filter('Table1','Default View', "column_name='A' and column_name='B'") /* (1)! */
  1. Find the rows which contains both 'A' and 'B'


Number-based Column (Number columns)

base.filter('Table1', 'Default View', "column_name>18")
base.filter('Table1', 'Default View', "column_name>-10 and column_name<=0")
base.filter('Table1', 'Default View',"column_name<>20")
base.filter('Table1', 'Default View', "column_name=0")
base.filter('Table1', 'Default View',"column_name=''")
base.filter('Table1', 'Default View', "column_name+3>18")
base.filter('Table1', 'Default View', "column_name*2=18")
base.filter('Table1', 'Default View', "column_name-2=18")
base.filter('Table1', 'Default View', "column_name/2=18")
base.filter('Table1', 'Default View', "column_name^2=18")
base.filter('Table1', 'Default View', "column_name%2=1")


Date-based Column (Date, Created time, Last modified time columns)

base.filter('Table1', 'Default View', "column_name>'2020-1-30'")
base.filter('Table1', 'Default View', "column_name>='2019-1-1 5:30' and column_name<='2019-5-1 6:00'")
base.filter('Table1', 'Default View', "column_name='2020-1-1 10:59:59'")
base.filter('Table1', 'Default View', "column_name!=''")


Boolean-based Column (Checkbox columns)

base.filter('Table1', 'Default View','column_name=False')/* (1)! */
base.filter('Table1', 'Default View', "column_name=True")
  1. same as base.filter('Table1', "column_name=''")

querySet handling

The output of the base.filter function is a querySet object. Here are the methods of this object provided to simplify the operations on the filtered data.

all

Returns all filtered rows of the querySet in the form of a list.

querySet.all();

Output Array of row objects

Example

const querySet = base.filter('Table1', 'Default View', 'number = 5');
const list = querySet.all();
output.text(list);

count

Returns the number of filtered rows of the querySet.

querySet.count();

Output Number

Example

const querySet = base.filter('Table1', 'Default View', 'number = 5');
const count = querySet.count();
output.text(`The querySet contains ${count} rows`);

first

Return the first filtered row of the querySet.

querySet.first();

Output Single row object (undefined if the querySet contains no row)

Example

const querySet = base.filter('Table1', 'Default View', 'number = 5');
const row = querySet.first();

last

Return the last filtered row of the querySet.

querySet.last();

Output Single row object (undefined if the querySet contains no row)

Example

const querySet = base.filter('Table1', 'Default View', 'number = 5');
const row = querySet.last();

delete

Delete all filtered rows of the querySet and return the number of rows successfully deleted.

querySet.delete();

Output Number

Example

const querySet = base.filter('Table1', 'Default View', 'number = 5');
const count = querySet.delete();
output.text(`${count} rows successfully deleted!`);

update

Modify the row data according to therowData Object and return the updated rows.

querySet.update(rowData: Object/* (1)! */);
  1. rowData: object (pairs of key:value, each key being the name of a column)

Output Array of row objects (empty Array if no filtered row)

Example

// Modify the content of the Name column of all filtered rows to xxxx
const querySet = base.filter('Table1', 'Default View', 'number = 5');
const rows = querySet.update({Name: 'xxxx'});

filter

Further filtering using the filterExpression conditional statement.

querySet.filter(filterExpression: String);

Output Single querySet object

Example

// Filter out the rows with the value of Tom in the Name column of querySet1
const querySet1 = base.filter('Table1', 'Default View', 'number = 5');
const querySet2 = querySet1.filter("Name = 'Tom'");

get

Return the first row of the querySet that meets the conditions of the new filterExpression. This is equivalent to querySet.filter(filterExpression).first()

querySet.get(filterExpression: String);

Output Single row object (undefined if no row meets the conditions of the filterExpression, #ERROR! if the filterExpression is wrong)

Example

// Get the first data of Tom in the Name column of the querySet
const querySet = base.filter('Table1', 'Default View', 'number = 5');
const row = querySet.get("Name = 'Tom'");