用户 REFERENCE 列的 PostgreSQL 迁移语法错误
PostgreSQL Migration syntax error with user REFERENCE column
我正在处理 PostgreSQL 数据库。为了在其他不错的功能中实施迁移版本控制管理,我发现 Migrate 一个用 Go 编写的数据库迁移,并将其添加到我的项目中。到目前为止,我还没有遇到任何问题,但是,我遇到了一个问题,如果没有 hacky 解决方法,我将无法克服。
所以上下文如下,我有如下所示的迁移文件,其中包含 4 tables:user、sport、challenge 和 activity。当我 运行 migrate up
, migrate
抛出以下错误:
(details: pq: syntax error at or near "user")
error: Dirty database version 1. Fix and force version.
如果我从 table 中删除 user_id
列,migrate
工作正常,所有 table 都会创建。但是,就像 user_id
现在一样,它不起作用。
有人会知道这里有什么问题吗?使我的迁移正常工作的修复方法是什么?
向上迁移文件:
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE TABLE IF NOT EXISTS "user"(
"id" UUID NOT NULL PRIMARY KEY DEFAULT uuid_generate_v4(),
"username" VARCHAR(50) UNIQUE NOT NULL,
"password" VARCHAR(50) NOT NULL,
"created_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS "sport"(
"id" UUID NOT NULL PRIMARY KEY DEFAULT uuid_generate_v4(),
"sport_name" VARCHAR(50) UNIQUE NOT NULL,
"created_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS "challenge"(
"id" UUID NOT NULL PRIMARY KEY DEFAULT uuid_generate_v4(),
"challenge_name" VARCHAR(50) UNIQUE NOT NULL,
"created_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
"sport_id" UUID NOT NULL REFERENCES sport(id),
"distance_goal" VARCHAR(50),
"time_goal" VARCHAR(50)
);
CREATE TABLE IF NOT EXISTS "activity"(
"id" UUID NOT NULL PRIMARY KEY DEFAULT uuid_generate_v4(),
"created_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
"date" VARCHAR(50),
"time" VARCHAR(50),
"distance" VARCHAR(50),
"user_id" UUID NOT NULL REFERENCES user(id),
"sport_id" UUID NOT NULL REFERENCES sport(id),
"challenge_id" UUID REFERENCES challenge(id)
);
这里有一个 docker-compose,其中包含 运行 迁移和 Postgres 数据库(如果您的环境中没有):) :
version: '3.3'
services:
# Based in
steelman_db:
image: postgres:13
networks:
database_net:
aliases:
- database_host
environment:
POSTGRES_DB: steelman_db
POSTGRES_USER: steelman
POSTGRES_PASSWORD: steelman
ports:
- "5432"
healthcheck:
test: pg_isready -U steelman -d steelman_db
interval: 10s
timeout: 30s
retries: 5
migrate:
image: migrate/migrate
networks:
- database_net
volumes:
- ./db/migrations:/migrations
command: ["-path", "/migrations", "-database", "postgres://steelman:steelman@database_host:5432/steelman_db?sslmode=disable", "up"]
restart: "on-failure"
depends_on:
- steelman_db
links:
- steelman_db
networks:
database_net:
问题是 user
是一个 Reserved word 并且在使用时需要用双引号引起来。换句话说,它不是标识符的好名称。如果你想继续使用它,那么你必须改变:
"user_id" UUID NOT NULL REFERENCES user(id),
至:
"user_id" UUID NOT NULL REFERENCES "user"(id),
以及您在其他任何地方使用它。
我正在处理 PostgreSQL 数据库。为了在其他不错的功能中实施迁移版本控制管理,我发现 Migrate 一个用 Go 编写的数据库迁移,并将其添加到我的项目中。到目前为止,我还没有遇到任何问题,但是,我遇到了一个问题,如果没有 hacky 解决方法,我将无法克服。
所以上下文如下,我有如下所示的迁移文件,其中包含 4 tables:user、sport、challenge 和 activity。当我 运行 migrate up
, migrate
抛出以下错误:
(details: pq: syntax error at or near "user")
error: Dirty database version 1. Fix and force version.
如果我从 table 中删除 user_id
列,migrate
工作正常,所有 table 都会创建。但是,就像 user_id
现在一样,它不起作用。
有人会知道这里有什么问题吗?使我的迁移正常工作的修复方法是什么?
向上迁移文件:
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE TABLE IF NOT EXISTS "user"(
"id" UUID NOT NULL PRIMARY KEY DEFAULT uuid_generate_v4(),
"username" VARCHAR(50) UNIQUE NOT NULL,
"password" VARCHAR(50) NOT NULL,
"created_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS "sport"(
"id" UUID NOT NULL PRIMARY KEY DEFAULT uuid_generate_v4(),
"sport_name" VARCHAR(50) UNIQUE NOT NULL,
"created_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS "challenge"(
"id" UUID NOT NULL PRIMARY KEY DEFAULT uuid_generate_v4(),
"challenge_name" VARCHAR(50) UNIQUE NOT NULL,
"created_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
"sport_id" UUID NOT NULL REFERENCES sport(id),
"distance_goal" VARCHAR(50),
"time_goal" VARCHAR(50)
);
CREATE TABLE IF NOT EXISTS "activity"(
"id" UUID NOT NULL PRIMARY KEY DEFAULT uuid_generate_v4(),
"created_at" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
"date" VARCHAR(50),
"time" VARCHAR(50),
"distance" VARCHAR(50),
"user_id" UUID NOT NULL REFERENCES user(id),
"sport_id" UUID NOT NULL REFERENCES sport(id),
"challenge_id" UUID REFERENCES challenge(id)
);
这里有一个 docker-compose,其中包含 运行 迁移和 Postgres 数据库(如果您的环境中没有):) :
version: '3.3'
services:
# Based in
steelman_db:
image: postgres:13
networks:
database_net:
aliases:
- database_host
environment:
POSTGRES_DB: steelman_db
POSTGRES_USER: steelman
POSTGRES_PASSWORD: steelman
ports:
- "5432"
healthcheck:
test: pg_isready -U steelman -d steelman_db
interval: 10s
timeout: 30s
retries: 5
migrate:
image: migrate/migrate
networks:
- database_net
volumes:
- ./db/migrations:/migrations
command: ["-path", "/migrations", "-database", "postgres://steelman:steelman@database_host:5432/steelman_db?sslmode=disable", "up"]
restart: "on-failure"
depends_on:
- steelman_db
links:
- steelman_db
networks:
database_net:
问题是 user
是一个 Reserved word 并且在使用时需要用双引号引起来。换句话说,它不是标识符的好名称。如果你想继续使用它,那么你必须改变:
"user_id" UUID NOT NULL REFERENCES user(id),
至:
"user_id" UUID NOT NULL REFERENCES "user"(id),
以及您在其他任何地方使用它。