Add model
Рецепт: создать новую модель (таблицу) в Serverpod.
Шаг 1: Создать .spy.yaml в lib/src/models/¶
# onewallet_base_server/lib/src/models/my_record.spy.yaml
class: MyRecord
table: my_record
fields:
userId: int
status: String
amount: int?
note: String?
createdAt: DateTime
updatedAt: DateTime?
indexes:
my_record_user_idx:
fields: userId
my_record_status_idx:
fields: status
Поддерживаемые типы полей:
- int, double, bool, String, DateTime
- String?, int? и т.д. — nullable
- List<String>? — массив
- MyOtherModel? — ссылка на другую модель (без FK constraint)
Шаг 2: serverpod generate¶
После выполнения:
- lib/src/generated/my_record.dart — Dart-класс с .db accessor
- migrations/<timestamp>_<hash>/migration.sql — SQL для создания таблицы
- migrations/<timestamp>_<hash>/definition.json — снимок схемы
Не редактировать сгенерированные файлы в lib/src/generated/.
Шаг 3: Проверить migration SQL¶
Ожидаемое содержимое — CREATE TABLE с camelCase именами колонок:
CREATE TABLE "my_record" (
"id" bigserial PRIMARY KEY,
"userId" bigint NOT NULL,
"status" text NOT NULL,
"amount" bigint,
"note" text,
"createdAt" timestamp without time zone NOT NULL,
"updatedAt" timestamp without time zone
);
Шаг 4: Применить миграцию¶
Для production/staging — применяется тем же способом, через Docker entrypoint.
Правила¶
camelCase в SQL — всегда цитировать:
Serverpod генерирует camelCase имена колонок. В любом raw SQL (unsafeQuery, unsafeExecute) их необходимо цитировать в двойных кавычках:
// Правильно
await session.db.unsafeQuery(
'SELECT "userId", "createdAt" FROM "my_record" WHERE "userId" = @id',
parameters: QueryParameters.named({'id': userId}),
);
// Неправильно — PostgreSQL превратит в lowercase
await session.db.unsafeQuery(
'SELECT userId, createdAt FROM my_record WHERE userId = @id',
...
);
Никаких ручных SQL-миграций:
Схема public.* управляется только через serverpod generate + --apply-migrations. Никогда не писать ALTER TABLE, CREATE TABLE и т.п. вручную.
Схема pm.* — не трогать:
PM-таблицы (схема pm.*) управляются Drizzle-миграциями в projects/payment-manager/. Serverpod не пишет в pm.*.