Как установить стандартную дату истечения срока действия для записи в таблице PostgreSQL при её создании?

Здравствуйте! 

У меня возникла проблема с созданием схемы для таблицы "verification". Я хотел бы, чтобы при регистрации аккаунта в таблицу добавлялась строка, где колонка "expires_at" устанавливала бы дату, равную неделе от момента создания записи. Однако при этом ОРМ формирует следующий запрос: 

<pre><code class="sql">CREATE TABLE "verification" (
	"id" serial PRIMARY KEY NOT NULL,
	"user_id" text NOT NULL,
	"identifier" text NOT NULL,
	"value" boolean DEFAULT false,
	"expires_at" timestamp DEFAULT dateadd(day, 7, getdate()) NOT NULL,
	"created_at" timestamp DEFAULT now() NOT NULL,
	"updated_at" timestamp DEFAULT now() NOT NULL
);</code></pre>

Проблема в том, что PostgreSQL сообщает об ошибке:

<pre><code class="bash">applying migrations...error: cannot use column reference in DEFAULT expression</code></pre>

Как правильно установить значение по умолчанию для колонки "expires_at"?
  • 14 марта 2025 г. 14:44
Ответы на вопрос 2
В PostgreSQL вы не можете использовать ссылки на другие столбцы таблицы в выражении по умолчанию для другого столбца. Чтобы установить дату истечения срока действия, равную одной неделе от момента создания записи, вы можете использовать триггер, который будет автоматически обновлять значение `expires_at` после вставки новой записи.

Вот шаги для создания таблицы `verification` с триггером:

1. **Создание таблицы**:
   Создайте таблицу `verification` без необходимости устанавливать значение по умолчанию для `expires_at`.

   ```sql
   CREATE TABLE verification (
       id serial PRIMARY KEY NOT NULL,
       user_id text NOT NULL,
       identifier text NOT NULL,
       value boolean DEFAULT false,
       expires_at timestamp NOT NULL,
       created_at timestamp DEFAULT now() NOT NULL,
       updated_at timestamp DEFAULT now() NOT NULL
   );
   ```

2. **Создание триггера**:
   Создайте функцию, которая будет обновлять `expires_at`, и триггер, который будет вызываться при вставке данных.

   ```sql
   CREATE OR REPLACE FUNCTION set_expiration()
   RETURNS TRIGGER AS $$
   BEGIN
       NEW.expires_at := NEW.created_at + interval '7 days';
       RETURN NEW;
   END;
   $$ LANGUAGE plpgsql;

   CREATE TRIGGER expiration_trigger
   BEFORE INSERT ON verification
   FOR EACH ROW
   EXECUTE FUNCTION set_expiration();
   ```

Теперь, когда вы будете вставлять записи в таблицу `verification`, значение `expires_at` будет автоматически устанавливаться на 7 дней после времени создания записи (`created_at`).

### Пример вставки записи:

```sql
INSERT INTO verification (user_id, identifier, value)
VALUES ('user1', 'identifier1', true);
```

После выполнения этого запроса PostgreSQL автоматически установит значение `expires_at` через 7 дней от времени вставки.
"expires_at" timestamp DEFAULT dateadd(day, 7, now()) NOT NULL
Похожие вопросы