Data Model

Felis’s data model is defined by a set of Pydantic classes defining the semantics of tabular data. In addition to the standard conceptual constructs of a relational database schema, such as tables and columns, Felis provides a way to attach extra metadata to these elements, like units of measurement on columns.

Schema

A schema is the top-level object in the data model and represents a collection of tables along with their indexes and constraints. A schema is defined by a name and will be instantiated as a schema object in PostgreSQL using CREATE SCHEMA and a database object in MySQL with CREATE DATABASE.

Schemas may contain the following fields:

name:

The name of this schema. This is the name that will be used to create the schema in the database.

@id:

An identifier for this schema. This may be used for relating schemas together at a higher level. Typically, the name of the schema can be used as the id.

description:

A textual description of this schema.

tables:

The list of tables in the schema. A schema must have one or more tables.

version:

Optional schema version description.

Schema Version

A schema version can be used to track changes to a schema over time. The version is defined by either a simple string or a more complex version object. Felis does not enforce any particular format for version strings. A version string could simply be defined as v1, for instance.

The schema version object has the following attributes:

current:

The current version of the schema.

compatible:

A list of fully compatible versions.

read_compatible:

A list of versions that are read-compatible. A read compatible version is one where a database created with the older version can be read by the newer version. An example of a non-read compatible change would be removing a column from a table.

While Felis does not enforce any particular format for version strings, it is recommended to use a format that can be compared using semantic versioning.

Table

A table represents a collection of columns along with their indexes and constraints and has these attributes:

name:

The name of this table. This is the name that will be used to create the table in the database.

@id:

A unique identifier for this table.

description:

A textual description of this table.

columns:

The list of columns in the table.

primaryKey:

The ID of the table’s primary key column or a list of IDs that make up a composite primary key.

constraints:

The list of constraints for the table. Refer to the Constraint section for more information.

indexes:

The list of indexes for the table. Refer to the Index section for more information.

A table may also have the following optional attributes:

tap:table_index:

The index of this table in a TAP schema. This is used to order the tables in public presentations of the schema.

mysql:charset:

The MySQL character set for the table.

mysql:engine:

The MySQL storage engine for the table.

Column

A column represents a single field in a table. A column has a name and a data type and may have additional metadata like units of measurement.

Columns have the following primary attributes:

name:

The name of this column. This is the name that will be used to create the column in the database.

@id:

A unique identifier for this column.

description:

A textual description of this column.

datatype:

The data type of this column. Valid datatypes are defined by the Felis type system.

autoincrement:

A boolean flag indicating whether this column is auto-incrementing.

length:

The length of the column. This is only applicable to certain data types.

nullable:

A boolean flag indicating whether this column can be null.

precision:

The precision of the column. This is current only applicable to columns with the timestamp datatype.

value:

The default value for this column.

A column may also have the following optional properties:

ivoa:unit:

The IVOA unit of this column.

fits:tunit:

The FITS TUNIT unit for this column [1].

ivoa:ucd:

The IVOA UCD for this column [1].

tap:column_index:

The index of this column in a TAP table. This is used to order the columns in public presentations of the table [2].

tap:principal:

A flag indicating whether this column is a “principal column” in a TAP table; principal columns represent a subset to be highlighted or used as a default in public presentations and query builders. This should be encoded as 0 or 1 [2].

tap:std:

A flag indicating whether this column is a representation of an element of an IVOA-standard data model. This should be encoded as 0 or 1 [2].

votable:arraysize:

The VOTable arraysize for this column [3].

votable:datatype:

The VOTable datatype for this column [3].

votable:xtype:

The VOTable xtype, if any, for this column [3].

mysql:datatype:

A MySQL data type override for this column.

postgresql:datatype:

A PostgreSQL data type override for this column.

Constraint

A constraint is a rule that restricts the values in a table. The most common type of constraint is a foreign key constraint.

Constraints have specific types specified by the @type field, which can be one of the following:

All types of constraints accept the following properties:

name:

The name of the constraint. This is the name that will be used to create the constraint in the database.

description:

A textual description of this constraint.

@id:

A unique identifier for this constraint.

deferrable:

A boolean flag indicating whether this constraint is deferrable. This will emit a DEFERRABLE clause when creating the constraint in the database.

initially:

The initial deferrable state of the constraint. This will emit an INITIALLY <value> clause when creating the constraint in the database.

annotations:

A list of annotations for this constraint [4].

@type:

This is a special field which indicates the type of the constraint. The value of this field will determine the type of the constraint object that is created and what additional fields are allowed on the object.

Constraint Types

A foreign key constraint is a rule that enforces referential integrity between two tables. The constraint is defined by a column in the current table that references a column in another table. Foreign key constraints may have the following additional attributes:

columns:

One or more column names in the current table that are part of the foreign key. This should be one or more @id values pointing to columns in the current table.

referencedColumns:

The columns referenced by the foreign key. This should be one or more @id values pointing to columns in another table.

A check constraint is a rule that restricts the values in a column. The constraint is defined by a SQL expression. Check constraints may have the following additional attributes:

expression:

The SQL expression that defines the constraint.

A unique constraint is a rule that enforces uniqueness of values in a column or set of columns. The constraint is defined by one or more columns in the table. Unique constraints may have the following additional attributes:

columns:

One or more column names in the current table that are part of the unique constraint. This should be one or more @id values pointing to columns in the current table.

Index

An index is a data structure that improves the speed of data retrieval operations on a table. Indexes are defined by one or more columns in the table and have the following attributes:

name:

The name of the index. This is the name that will be used to create the index in the database.

description:

A textual description of this index.

@id:

A unique identifier for this index.

columns:

The list of columns in the table that are part of the index. This should be one or more @id values pointing to columns in the table [5].

expressions:

The list of SQL expressions that are part of the index. This is only applicable to indexes that are created using expressions [5].

Warning

Databases may be updated with additional indexes that are not defined in the schema. These indexes will not be reflected in the Felis schema.