From bc2b0e40c6617d766f4b49d476e847ac14d234b3 Mon Sep 17 00:00:00 2001 From: kurihada Date: Sun, 1 Mar 2026 22:44:44 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E7=94=9F=E4=BA=A7?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=BA=93=20schema=20=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E8=84=9A=E6=9C=AC=E7=9A=84=E5=8F=8C=E9=87=8D=20IF=20NOT=20EXIS?= =?UTF-8?q?TS=20bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit prisma db push 生成的 .schema 已自带 CREATE TABLE IF NOT EXISTS, 旧脚本的 sed 替换会生成 IF NOT EXISTS IF NOT EXISTS 导致 SQL 语法错误, 建表全部静默失败。现在只对 CREATE INDEX 做 IF NOT EXISTS 补充。 --- Dockerfile | 8 ++++---- docker-entrypoint.sh | 28 +++++++++++++++++++++++++--- 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/Dockerfile b/Dockerfile index 619fc17..f89b10c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,25 +17,25 @@ COPY . . ARG NEXT_PUBLIC_AMAP_API_KEY ENV NEXT_PUBLIC_AMAP_API_KEY=${NEXT_PUBLIC_AMAP_API_KEY} RUN npx prisma generate +ENV DATABASE_URL="file:./template.db" +RUN npx prisma db push RUN npm run build # --- Production --- FROM base AS runner WORKDIR /app ENV NODE_ENV=production +RUN apk add --no-cache sqlite RUN addgroup --system --gid 1001 nodejs RUN adduser --system --uid 1001 nextjs COPY --from=builder /app/public ./public COPY --from=builder /app/prisma ./prisma +COPY --from=builder /app/prisma/template.db ./template.db COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static -# Prisma CLI + engines for schema sync on startup -COPY --from=deps /app/node_modules/prisma ./node_modules/prisma -COPY --from=deps /app/node_modules/@prisma ./node_modules/@prisma - COPY docker-entrypoint.sh ./ RUN chmod +x docker-entrypoint.sh diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 6167b1c..43f7614 100644 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -1,14 +1,36 @@ #!/bin/sh set -e +TEMPLATE="/app/template.db" DB="/app/data/prod.db" if [ ! -f "$DB" ]; then - echo "[db] First run — initializing database" + echo "[db] First run — creating database from template" + cp "$TEMPLATE" "$DB" + exec node server.js fi echo "[db] Syncing schema..." -node ./node_modules/prisma/build/index.js db push --skip-generate --accept-data-loss 2>&1 -echo "[db] Schema sync complete" +# Schema already contains "CREATE TABLE IF NOT EXISTS" from Prisma. +# Only indexes need the IF NOT EXISTS addition. +sqlite3 "$TEMPLATE" ".schema" | \ + sed 's/CREATE INDEX /CREATE INDEX IF NOT EXISTS /g' | \ + sed 's/CREATE UNIQUE INDEX /CREATE UNIQUE INDEX IF NOT EXISTS /g' | \ + sqlite3 "$DB" + +# Add missing columns to existing tables +for table in $(sqlite3 "$TEMPLATE" "SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' AND name NOT LIKE '_prisma%'"); do + prod_cols=$(sqlite3 "$DB" "PRAGMA table_info('$table')" | cut -d'|' -f2) + + sqlite3 "$TEMPLATE" "PRAGMA table_info('$table')" | while IFS='|' read -r _cid name type notnull dflt _pk; do + if ! echo "$prod_cols" | grep -qx "$name"; then + alter="ALTER TABLE \"$table\" ADD COLUMN \"$name\" $type" + [ -n "$dflt" ] && alter="$alter DEFAULT $dflt" + sqlite3 "$DB" "$alter" && echo "[db] + $table.$name" || echo "[db] WARN: failed to add $table.$name" + fi + done +done + +echo "[db] Schema sync complete" exec node server.js