@subsquid/typeorm-store
This page describes the interface of the classes from the @subsquid/typeorm-store NPM package. If you’re looking for a guide on saving squid data to databases and the related workflows, check out the Saving to PostgreSQL page.
TypeormDatabase constructor arguments
The argument of the TypeormDatabase class constructor may have the following fields:
stateSchema: string: the name of the database schema that the processor uses to persist its status (hash + height of the highest reached block). Useful for making sure that each processor uses its own state schema when running multiple processors against the same database (e.g. in a multichain setting). Default:'squid_processor'. This affects only the processor’s own status tables; to relocate the entity (data) tables, use theDB_SCHEMAenvironment variable.isolationLevel: 'SERIALIZABLE' | 'READ COMMITTED' | 'REPEATABLE READ': sets the transaction isolation level of processor transactions. Default:'SERIALIZABLE'.supportHotBlocks: boolean: controls the support for hot blocks. Necessary in all squids that must be able to handle short-lived blockchain forks. That includes all squids that index chain data in near-real time using RPC endpoints. Default:true.projectDir: string: the folder whereTypeormDatabasewill look for the TypeORM model definition and migrations. It resolvessrc/modelunder ts-node andlib/modelin compiled runs, plusdb/migrations. Default:process.cwd().
Store interface
Processor transactions retry PostgreSQL serialization failures with code
40001 up to three times after the first attempt. The data handler can
therefore run more than once for the same batch. Keep external side effects
idempotent or perform them outside the handler.
Batch access methods
upsert(e: E | E[])
Upsert a single or multiple entities to the database. Does not cascade the upsert to the relations.
save(e: E | E[])
Alias for upsert().
insert(e: E | E[])
Inserts a given entity or entities into the database. Does not check if the entity(s) exist in the database and will fail if a duplicate is inserted. Executes a primitive INSERT operation without cascading to the relations.
remove(e: E | E[] | EntityClass<E>, id?: string | string[])
Deletes a given entity or entities from the database. Accepts either an object or an entity ID(s). Does not cascade the deletion.
TypeORM methods
The store intentionally exposes a restricted subset of TypeORM’sEntityManager. Its find options support where, relations, order, and
comment, plus skip and take for multi-row methods. findOne(),
findOneBy(), and get() return undefined instead of TypeORM’s null when
nothing matches.
get
Get an entity by ID or with the restricted FindOneOptions accepted by
findOne(). It returns undefined when no row matches.
count
Count the number of entities matching a where filter.
countBy
Count the number of entities matching a filter.
find
Return a list matching a where filter.
findBy
Return a list matching a filter.
findOne
Return the first entity matching a where filter.
findOneBy
Return the first entity matching a filter.
findOneOrFail
Throws if nothing is found.
findOneByOrFail
Throws if nothing is found.
Find Operators
find() and findXXX() methods support the following operators:
In(contains in array)NotLessThanLessThanOrEqualMoreThanMoreThanOrEqualLikeILikeBetweenAnyIsNullRaw(raw SQL fragments)
FindOption docs.
Example
Joining relations
To load an entity with relations, userelations field on the find options and specify which relations should be joined:
Database connection parameters
Database credentials must be supplied via the environment variables:DB_HOST(defaultlocalhost)DB_PORT(default5432)DB_NAME(defaultpostgres)DB_USER(defaultpostgres)DB_PASS(defaultpostgres)DB_SSL(defaultfalse)DB_SSL_REJECT_UNAUTHORIZED(defaulttrue)DB_URL(defaultundefined, see the DB_URL section)DB_SCHEMA(defaultundefined, see the DB_SCHEMA section)DB_SCHEMA_INCLUDE_PUBLIC(defaultfalse, see the DB_SCHEMA section)
When deploying to Cloud with the Postgres addon enabled in the manifest, any user-supplied values are overwritten for most of these variables. See Variable shadowing.
typeorm-store also supports the following variables for connecting to databases that require client-side SSL:
DB_SSL_CA- the root certificate in plain textDB_SSL_CA_FILE- path to a root certificate fileDB_SSL_CERT- client certificate in plain textDB_SSL_CERT_FILE- path to client certificate in plain textDB_SSL_KEY- client key in plain textDB_SSL_KEY_FILE- path to client key in plain text
DB_URL
When set, DB_URL takes precedence over all individual variables. Its format is as follows:
parameter_list is an &-separated list of assignments of SSL connection parameters:
ssl=(0|1|true|false)sslmode=(disable|disabled|no-verify|prefer|require|verify-ca|verify-full)sslcert=<path_to_cert_file>sslkey=<path_to_key_file>sslrootcert=<path_to_root_cert_file>
DB_URL is set, its host, port, and database are authoritative;
DB_HOST, DB_PORT, and DB_NAME are ignored. DB_USER and DB_PASS fill in
only a username or password omitted from the URL. SSL values in the URL take
precedence over SSL environment variables.
DB_SCHEMA
By default a squid keeps its entity tables in the connection’s default Postgres schema (usually public). Set DB_SCHEMA to place them in a named Postgres schema instead:
DB_SCHEMA(default:undefined) — name of the Postgres schema that holds the entity (data) tables. When set, the store connects with asearch_pathpointing at this schema, so all entity reads and writes resolve to it without any change to the generated SQL. The name must be a plain SQL identifier (matching[A-Za-z_][A-Za-z0-9_]*), and its case is preserved.DB_SCHEMA_INCLUDE_PUBLIC(default:false) — whentrue,publicis appended to thesearch_pathafterDB_SCHEMA. Enable it only if your squid references objects that live inpublic, such as Postgres extensions; otherwise the data schema stays fully isolated.
squid-typeorm-migration apply issues a CREATE SCHEMA IF NOT EXISTS before running the migrations, and the migrations ledger lands in it too — so no manual setup is required.
DB_SCHEMA is independent of the stateSchema constructor argument: DB_SCHEMA selects where the entity data lives, while stateSchema selects where the processor keeps its status. The two may be set to the same value, in which case a chain’s data and processor state share a single schema. If you use such an arrangement, please take care to avoid collisions with system table names: hot_block, hot_change_log, migrations, status, template_registry.
The GraphQL server reads DB_SCHEMA too, so OpenReader serves the entities straight from the same schema.