Links
Comment on page

Define Your Schema

You need to set up your schema in your app project. This involves defining your schema in code using the PowerSync syntax.
This schema represents a "view" of the downloaded data. No migrations are required — the schema is applied directly when the PowerSync database is constructed.
For details on how Postgres types are mapped to the types below, see the section on Types in the Sync Rules documentation.
Generate schema automatically
In the PowerSync Dashboard, the schema can be generated based off your sync rules by right-clicking on an instance and selecting Generate client-side schema. Currently, the schema can be generated in JavaScript or Dart.

Flutter

The PowerSyncDatabase constructor takes a schema parameter.
The types available are text, integer and real. These should map directly to the values produced by the Sync Rules. If a value doesn't match, it is cast automatically.
Example:
import 'package:powersync/powersync.dart';
const schema = Schema(([
Table('todos', [
Column.text('list_id'),
Column.text('created_at'),
Column.text('completed_at'),
Column.text('description'),
Column.integer('completed'),
Column.text('created_by'),
Column.text('completed_by'),
], indexes: [
// Index to allow efficient lookup within a list
Index('list', [IndexedColumn('list_id')])
]),
Table('lists', [
Column.text('created_at'),
Column.text('name'),
Column.text('owner_id')
])
]));

React Native & Expo

RNQSPowerSyncDatabaseOpenFactory takes a schema parameter.
The types available are TEXT, INTEGER and REAL. These should map directly to the values produced by the Sync Rules. If a value doesn't match, it is cast automatically.
Example:
import {
Column,
ColumnType,
Index,
IndexedColumn,
Schema,
Table
} from '@journeyapps/powersync-sdk-react-native';
export const AppSchema = new Schema([
new Table({
name: 'todos',
columns: [
new Column({ name: 'list_id', type: ColumnType.TEXT }),
new Column({ name: 'created_at', type: ColumnType.TEXT }),
new Column({ name: 'completed_at', type: ColumnType.TEXT }),
new Column({ name: 'description', type: ColumnType.TEXT }),
new Column({ name: 'completed', type: ColumnType.INTEGER }),
new Column({ name: 'created_by', type: ColumnType.TEXT }),
new Column({ name: 'completed_by', type: ColumnType.TEXT })
],
indexes: [new Index({ name: 'list', columns: [new IndexedColumn({ name: 'list_id' })] })]
}),
new Table({
name: 'lists',
columns: [
new Column({ name: 'created_at', type: ColumnType.TEXT }),
new Column({ name: 'name', type: ColumnType.TEXT }),
new Column({ name: 'owner_id', type: ColumnType.TEXT })
]
})
]);

JS Web

WASQLitePowerSyncDatabaseOpenFactory takes a schema parameter.
The types available are TEXT, INTEGER and REAL. These should map directly to the values produced by the Sync Rules. If a value doesn't match, it is cast automatically.
Example:
import {
Column,
ColumnType,
Index,
IndexedColumn,
Schema,
Table
} from '@journeyapps/powersync-sdk-web';
export const AppSchema = new Schema([
new Table({
name: 'todos',
columns: [
new Column({ name: 'list_id', type: ColumnType.TEXT }),
new Column({ name: 'created_at', type: ColumnType.TEXT }),
new Column({ name: 'completed_at', type: ColumnType.TEXT }),
new Column({ name: 'description', type: ColumnType.TEXT }),
new Column({ name: 'completed', type: ColumnType.INTEGER }),
new Column({ name: 'created_by', type: ColumnType.TEXT }),
new Column({ name: 'completed_by', type: ColumnType.TEXT })
],
indexes: [new Index({ name: 'list', columns: [new IndexedColumn({ name: 'list_id' })] })]
}),
new Table({
name: 'lists',
columns: [
new Column({ name: 'created_at', type: ColumnType.TEXT }),
new Column({ name: 'name', type: ColumnType.TEXT }),
new Column({ name: 'owner_id', type: ColumnType.TEXT })
]
})
]);