Browse Source

Switch database from MySQL to PostgreSQL, update dependencies, and modify migration scripts accordingly. Adjust README and configuration files to reflect the new database setup.

tags/pure-sql-nuxt4
npmrun 6 days ago
parent
commit
58d646a9ed
  1. 2
      .env.example
  2. 2
      README.md
  3. 27
      build-files/migrate.js
  4. 35
      bun.lock
  5. 8
      package.json
  6. 2
      packages/drizzle-pkg/drizzle.config.ts
  7. 9
      packages/drizzle-pkg/lib/db.ts
  8. 12
      packages/drizzle-pkg/lib/schema/schema.ts
  9. 13
      packages/drizzle-pkg/migrations/0000_init.sql
  10. 67
      packages/drizzle-pkg/migrations/meta/0000_snapshot.json
  11. 6
      packages/drizzle-pkg/migrations/meta/_journal.json
  12. 7
      scripts/migrate-test.sh
  13. 42
      scripts/migrate.js
  14. 2
      server/api/hello.ts
  15. 5
      server/plugins/00.global.ts

2
.env.example

@ -1 +1 @@
DATABASE_URL=mysql://root:xxxxxxxx@localhost:3306/nuxt-db DATABASE_URL=postgresql://postgres:123456qaz@localhost:6666/postgres

2
README.md

@ -9,4 +9,4 @@
## 开发与部署 ## 开发与部署
用 Linux 开发与部署,包管理器采用 bun@1.3.11。数据库为 **MySQL**(通过 `DATABASE_URL` 连接;本地可参考 `.env.example` 复制为 `.env.local`)。部署时可直接打包 `.output` 目录,在服务器环境执行迁移命令,省时省力。 用 Linux 开发与部署,包管理器采用 bun@1.3.11。数据库为 **postgres**(通过 `DATABASE_URL` 连接;本地可参考 `.env.example` 复制为 `.env.local`)。部署时可直接打包 `.output` 目录,在服务器环境执行迁移命令,省时省力。

27
build-files/migrate.js

@ -1,43 +1,32 @@
import { drizzle } from 'drizzle-orm/mysql2' import { drizzle } from 'drizzle-orm/node-postgres'
import { migrate } from 'drizzle-orm/mysql2/migrator' import { migrate } from 'drizzle-orm/node-postgres/migrator'
import { createConnection } from 'mysql2/promise' import { Pool } from 'pg'
import path from 'node:path' import path from 'node:path'
import { fileURLToPath } from 'node:url' import { fileURLToPath } from 'node:url'
/**
* 考虑做成一个脚本不是在这里执行暂时无法保证一定在其它插件前最先运行
*/
/**
* 自动执行 MySQL 数据库迁移
* 等同于命令drizzle-kit migrate
*/
export async function runMigrations() { export async function runMigrations() {
const databaseUrl = process.env.DATABASE_URL const databaseUrl = process.env.DATABASE_URL
if (!databaseUrl) { if (!databaseUrl) {
throw new Error('DATABASE_URL 未设置') throw new Error('DATABASE_URL 未设置')
} }
const connection = await createConnection({ const pool = new Pool({ connectionString: databaseUrl })
uri: databaseUrl, const db = drizzle(pool)
})
const db = drizzle(connection)
try { try {
console.log('🚀 开始执行 MySQL 迁移...') console.log('🚀 开始执行 PostgreSQL 迁移...')
const migrationsFolder = path.resolve(process.cwd(), 'migrations') const migrationsFolder = path.resolve(process.cwd(), 'migrations')
await migrate(db, { await migrate(db, {
migrationsFolder, migrationsFolder,
}) })
console.log('✅ MySQL 迁移完成!') console.log('✅ PostgreSQL 迁移完成!')
} catch (err) { } catch (err) {
console.log('❌ 迁移失败:', err) console.log('❌ 迁移失败:', err)
throw err throw err
} finally { } finally {
await connection.end() await pool.end()
} }
} }

35
bun.lock

@ -6,17 +6,18 @@
"name": "person-panel", "name": "person-panel",
"dependencies": { "dependencies": {
"dotenv": "17.4.1", "dotenv": "17.4.1",
"drizzle-orm": "0.45.2", "drizzle-orm": "^0.45.2",
"drizzle-pkg": "workspace:*", "drizzle-pkg": "workspace:*",
"drizzle-seed": "0.3.1", "drizzle-seed": "0.3.1",
"log4js": "^6.9.1", "log4js": "^6.9.1",
"logger": "workspace:*", "logger": "workspace:*",
"mysql2": "3.22.0",
"nuxt": "4.4.2", "nuxt": "4.4.2",
"pg": "8.20.0",
"vue": "3.5.32", "vue": "3.5.32",
"vue-router": "5.0.4", "vue-router": "5.0.4",
}, },
"devDependencies": { "devDependencies": {
"@types/pg": "^8.20.0",
"drizzle-kit": "0.31.10", "drizzle-kit": "0.31.10",
"tsx": "4.21.0", "tsx": "4.21.0",
"typescript": "6.0.2", "typescript": "6.0.2",
@ -486,6 +487,8 @@
"@types/node": ["@types/node@25.6.0", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="], "@types/node": ["@types/node@25.6.0", "", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="],
"@types/pg": ["@types/pg@8.20.0", "", { "dependencies": { "@types/node": "*", "pg-protocol": "*", "pg-types": "^2.2.0" } }, "sha512-bEPFOaMAHTEP1EzpvHTbmwR8UsFyHSKsRisLIHVMXnpNefSbGA1bD6CVy+qKjGSqmZqNqBDV2azOBo8TgkcVow=="],
"@types/resolve": ["@types/resolve@1.20.2", "", {}, "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q=="], "@types/resolve": ["@types/resolve@1.20.2", "", {}, "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q=="],
"@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="], "@types/ws": ["@types/ws@8.18.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg=="],
@ -1074,6 +1077,22 @@
"perfect-debounce": ["perfect-debounce@2.1.0", "", {}, "sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g=="], "perfect-debounce": ["perfect-debounce@2.1.0", "", {}, "sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g=="],
"pg": ["pg@8.20.0", "", { "dependencies": { "pg-connection-string": "^2.12.0", "pg-pool": "^3.13.0", "pg-protocol": "^1.13.0", "pg-types": "2.2.0", "pgpass": "1.0.5" }, "optionalDependencies": { "pg-cloudflare": "^1.3.0" }, "peerDependencies": { "pg-native": ">=3.0.1" }, "optionalPeers": ["pg-native"] }, "sha512-ldhMxz2r8fl/6QkXnBD3CR9/xg694oT6DZQ2s6c/RI28OjtSOpxnPrUCGOBJ46RCUxcWdx3p6kw/xnDHjKvaRA=="],
"pg-cloudflare": ["pg-cloudflare@1.3.0", "", {}, "sha512-6lswVVSztmHiRtD6I8hw4qP/nDm1EJbKMRhf3HCYaqud7frGysPv7FYJ5noZQdhQtN2xJnimfMtvQq21pdbzyQ=="],
"pg-connection-string": ["pg-connection-string@2.12.0", "", {}, "sha512-U7qg+bpswf3Cs5xLzRqbXbQl85ng0mfSV/J0nnA31MCLgvEaAo7CIhmeyrmJpOr7o+zm0rXK+hNnT5l9RHkCkQ=="],
"pg-int8": ["pg-int8@1.0.1", "", {}, "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw=="],
"pg-pool": ["pg-pool@3.13.0", "", { "peerDependencies": { "pg": ">=8.0" } }, "sha512-gB+R+Xud1gLFuRD/QgOIgGOBE2KCQPaPwkzBBGC9oG69pHTkhQeIuejVIk3/cnDyX39av2AxomQiyPT13WKHQA=="],
"pg-protocol": ["pg-protocol@1.13.0", "", {}, "sha512-zzdvXfS6v89r6v7OcFCHfHlyG/wvry1ALxZo4LqgUoy7W9xhBDMaqOuMiF3qEV45VqsN6rdlcehHrfDtlCPc8w=="],
"pg-types": ["pg-types@2.2.0", "", { "dependencies": { "pg-int8": "1.0.1", "postgres-array": "~2.0.0", "postgres-bytea": "~1.0.0", "postgres-date": "~1.0.4", "postgres-interval": "^1.1.0" } }, "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA=="],
"pgpass": ["pgpass@1.0.5", "", { "dependencies": { "split2": "^4.1.0" } }, "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug=="],
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="], "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
"picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="], "picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="],
@ -1140,6 +1159,14 @@
"postcss-value-parser": ["postcss-value-parser@4.2.0", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="], "postcss-value-parser": ["postcss-value-parser@4.2.0", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="],
"postgres-array": ["postgres-array@2.0.0", "", {}, "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA=="],
"postgres-bytea": ["postgres-bytea@1.0.1", "", {}, "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ=="],
"postgres-date": ["postgres-date@1.0.7", "", {}, "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q=="],
"postgres-interval": ["postgres-interval@1.2.0", "", { "dependencies": { "xtend": "^4.0.0" } }, "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ=="],
"powershell-utils": ["powershell-utils@0.1.0", "", {}, "sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A=="], "powershell-utils": ["powershell-utils@0.1.0", "", {}, "sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A=="],
"pretty-bytes": ["pretty-bytes@7.1.0", "", {}, "sha512-nODzvTiYVRGRqAOvE84Vk5JDPyyxsVk0/fbA/bq7RqlnhksGpset09XTxbpvLTIjoaF7K8Z8DG8yHtKGTPSYRw=="], "pretty-bytes": ["pretty-bytes@7.1.0", "", {}, "sha512-nODzvTiYVRGRqAOvE84Vk5JDPyyxsVk0/fbA/bq7RqlnhksGpset09XTxbpvLTIjoaF7K8Z8DG8yHtKGTPSYRw=="],
@ -1240,6 +1267,8 @@
"source-map-support": ["source-map-support@0.5.21", "", { "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w=="], "source-map-support": ["source-map-support@0.5.21", "", { "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w=="],
"split2": ["split2@4.2.0", "", {}, "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg=="],
"sql-escaper": ["sql-escaper@1.3.3", "", {}, "sha512-BsTCV265VpTp8tm1wyIm1xqQCS+Q9NHx2Sr+WcnUrgLrQ6yiDIvHYJV5gHxsj1lMBy2zm5twLaZao8Jd+S8JJw=="], "sql-escaper": ["sql-escaper@1.3.3", "", {}, "sha512-BsTCV265VpTp8tm1wyIm1xqQCS+Q9NHx2Sr+WcnUrgLrQ6yiDIvHYJV5gHxsj1lMBy2zm5twLaZao8Jd+S8JJw=="],
"srvx": ["srvx@0.11.15", "", { "bin": { "srvx": "bin/srvx.mjs" } }, "sha512-iXsux0UcOjdvs0LCMa2Ws3WwcDUozA3JN3BquNXkaFPP7TpRqgunKdEgoZ/uwb1J6xaYHfxtz9Twlh6yzwM6Tg=="], "srvx": ["srvx@0.11.15", "", { "bin": { "srvx": "bin/srvx.mjs" } }, "sha512-iXsux0UcOjdvs0LCMa2Ws3WwcDUozA3JN3BquNXkaFPP7TpRqgunKdEgoZ/uwb1J6xaYHfxtz9Twlh6yzwM6Tg=="],
@ -1398,6 +1427,8 @@
"wsl-utils": ["wsl-utils@0.1.0", "", { "dependencies": { "is-wsl": "^3.1.0" } }, "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw=="], "wsl-utils": ["wsl-utils@0.1.0", "", { "dependencies": { "is-wsl": "^3.1.0" } }, "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw=="],
"xtend": ["xtend@4.0.2", "", {}, "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="],
"y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="], "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="],
"yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="], "yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="],

8
package.json

@ -8,8 +8,9 @@
"private": true, "private": true,
"scripts": { "scripts": {
"build": "nuxt build && bun run cp:db && bun --elide-lines=0 --filter drizzle-pkg build", "build": "nuxt build && bun run cp:db && bun --elide-lines=0 --filter drizzle-pkg build",
"dev": "nuxt dev --dotenv .env.local", "dev": "nuxt dev",
"cp:db": "cp build-files/run.sh .output/run.sh && cp .env.example .output/.env && cp build-files/migrate.js .output/server/migrate.js", "cp:db": "cp build-files/run.sh .output/run.sh && cp .env.example .output/.env && cp build-files/migrate.js .output/server/migrate.js",
"migrate:test": "sh scripts/migrate-test.sh",
"db:migrate": "bun --elide-lines=0 --filter drizzle-pkg migrate", "db:migrate": "bun --elide-lines=0 --filter drizzle-pkg migrate",
"db:generate": "bun --elide-lines=0 --filter drizzle-pkg generate --name", "db:generate": "bun --elide-lines=0 --filter drizzle-pkg generate --name",
"db:seed": "bun --elide-lines=0 --filter drizzle-pkg seed", "db:seed": "bun --elide-lines=0 --filter drizzle-pkg seed",
@ -19,17 +20,18 @@
}, },
"dependencies": { "dependencies": {
"dotenv": "17.4.1", "dotenv": "17.4.1",
"drizzle-orm": "^0.45.2",
"drizzle-pkg": "workspace:*", "drizzle-pkg": "workspace:*",
"drizzle-orm": "0.45.2",
"drizzle-seed": "0.3.1", "drizzle-seed": "0.3.1",
"log4js": "^6.9.1", "log4js": "^6.9.1",
"logger": "workspace:*", "logger": "workspace:*",
"mysql2": "3.22.0",
"nuxt": "4.4.2", "nuxt": "4.4.2",
"pg": "8.20.0",
"vue": "3.5.32", "vue": "3.5.32",
"vue-router": "5.0.4" "vue-router": "5.0.4"
}, },
"devDependencies": { "devDependencies": {
"@types/pg": "^8.20.0",
"drizzle-kit": "0.31.10", "drizzle-kit": "0.31.10",
"tsx": "4.21.0", "tsx": "4.21.0",
"typescript": "6.0.2" "typescript": "6.0.2"

2
packages/drizzle-pkg/drizzle.config.ts

@ -4,7 +4,7 @@ import { defineConfig } from 'drizzle-kit';
export default defineConfig({ export default defineConfig({
out: './migrations', out: './migrations',
schema: './lib/schema/*', schema: './lib/schema/*',
dialect: 'mysql', dialect: 'postgresql',
dbCredentials: { dbCredentials: {
url: process.env.DATABASE_URL! url: process.env.DATABASE_URL!
}, },

9
packages/drizzle-pkg/lib/db.ts

@ -1,6 +1,11 @@
import { drizzle } from "drizzle-orm/mysql2"; import { drizzle } from "drizzle-orm/node-postgres";
const _db = drizzle({ connection:{ uri: process.env.DATABASE_URL! }}); if (process.env.NODE_ENV === 'production') {
// 打包时需要保证migrator被引入
import('drizzle-orm/node-postgres/migrator')
}
const _db = drizzle(process.env.DATABASE_URL!);
export { _db as dbGlobal } export { _db as dbGlobal }

12
packages/drizzle-pkg/lib/schema/schema.ts

@ -1,8 +1,8 @@
import { int, mysqlTable, varchar } from "drizzle-orm/mysql-core"; import { integer, pgTable, varchar } from "drizzle-orm/pg-core";
export const usersTable = mysqlTable("users_table", { export const usersTable = pgTable("users_table", {
id: int().primaryKey().autoincrement(), id: integer().primaryKey().generatedAlwaysAsIdentity(),
name: varchar("name", { length: 255 }).notNull(), name: varchar().notNull(),
age: int().notNull(), age: integer().notNull(),
email: varchar("email", { length: 255 }).notNull().unique(), email: varchar().notNull().unique(),
}); });

13
packages/drizzle-pkg/migrations/0000_init.sql

@ -1,8 +1,7 @@
CREATE TABLE `users_table` ( CREATE TABLE "users_table" (
`id` int AUTO_INCREMENT NOT NULL, "id" integer PRIMARY KEY GENERATED ALWAYS AS IDENTITY (sequence name "users_table_id_seq" INCREMENT BY 1 MINVALUE 1 MAXVALUE 2147483647 START WITH 1 CACHE 1),
`name` varchar(255) NOT NULL, "name" varchar NOT NULL,
`age` int NOT NULL, "age" integer NOT NULL,
`email` varchar(255) NOT NULL, "email" varchar NOT NULL,
CONSTRAINT `users_table_id` PRIMARY KEY(`id`), CONSTRAINT "users_table_email_unique" UNIQUE("email")
CONSTRAINT `users_table_email_unique` UNIQUE(`email`)
); );

67
packages/drizzle-pkg/migrations/meta/0000_snapshot.json

@ -1,70 +1,75 @@
{ {
"version": "5", "id": "ccacc841-1a4a-434b-bfaa-8d18a9a641b2",
"dialect": "mysql",
"id": "dc6e882d-3e66-48c7-8d83-de136ee1cd98",
"prevId": "00000000-0000-0000-0000-000000000000", "prevId": "00000000-0000-0000-0000-000000000000",
"version": "7",
"dialect": "postgresql",
"tables": { "tables": {
"users_table": { "public.users_table": {
"name": "users_table", "name": "users_table",
"schema": "",
"columns": { "columns": {
"id": { "id": {
"name": "id", "name": "id",
"type": "int", "type": "integer",
"primaryKey": false, "primaryKey": true,
"notNull": true, "notNull": true,
"autoincrement": true "identity": {
"type": "always",
"name": "users_table_id_seq",
"schema": "public",
"increment": "1",
"startWith": "1",
"minValue": "1",
"maxValue": "2147483647",
"cache": "1",
"cycle": false
}
}, },
"name": { "name": {
"name": "name", "name": "name",
"type": "varchar(255)", "type": "varchar",
"primaryKey": false, "primaryKey": false,
"notNull": true, "notNull": true
"autoincrement": false
}, },
"age": { "age": {
"name": "age", "name": "age",
"type": "int", "type": "integer",
"primaryKey": false, "primaryKey": false,
"notNull": true, "notNull": true
"autoincrement": false
}, },
"email": { "email": {
"name": "email", "name": "email",
"type": "varchar(255)", "type": "varchar",
"primaryKey": false, "primaryKey": false,
"notNull": true, "notNull": true
"autoincrement": false
} }
}, },
"indexes": {}, "indexes": {},
"foreignKeys": {}, "foreignKeys": {},
"compositePrimaryKeys": { "compositePrimaryKeys": {},
"users_table_id": {
"name": "users_table_id",
"columns": [
"id"
]
}
},
"uniqueConstraints": { "uniqueConstraints": {
"users_table_email_unique": { "users_table_email_unique": {
"name": "users_table_email_unique", "name": "users_table_email_unique",
"nullsNotDistinct": false,
"columns": [ "columns": [
"email" "email"
] ]
} }
}, },
"checkConstraint": {} "policies": {},
"checkConstraints": {},
"isRLSEnabled": false
} }
}, },
"enums": {},
"schemas": {},
"sequences": {},
"roles": {},
"policies": {},
"views": {}, "views": {},
"_meta": { "_meta": {
"columns": {},
"schemas": {}, "schemas": {},
"tables": {}, "tables": {}
"columns": {}
},
"internal": {
"tables": {},
"indexes": {}
} }
} }

6
packages/drizzle-pkg/migrations/meta/_journal.json

@ -1,11 +1,11 @@
{ {
"version": "7", "version": "7",
"dialect": "mysql", "dialect": "postgresql",
"entries": [ "entries": [
{ {
"idx": 0, "idx": 0,
"version": "5", "version": "7",
"when": 1775843596838, "when": 1775935934813,
"tag": "0000_init", "tag": "0000_init",
"breakpoints": true "breakpoints": true
} }

7
scripts/migrate-test.sh

@ -0,0 +1,7 @@
if [ -f .env ]; then
export $(grep -v '^#' .env | xargs)
fi
echo "DATABASE_URL: $DATABASE_URL"
node scripts/migrate.js

42
scripts/migrate.js

@ -0,0 +1,42 @@
import { drizzle } from 'drizzle-orm/node-postgres'
import { migrate } from 'drizzle-orm/node-postgres/migrator'
import { Pool } from 'pg'
import path from 'node:path'
import { fileURLToPath } from 'node:url'
export async function runMigrations() {
const databaseUrl = process.env.DATABASE_URL
if (!databaseUrl) {
throw new Error('DATABASE_URL 未设置')
}
const pool = new Pool({ connectionString: databaseUrl })
const db = drizzle(pool)
try {
console.log('🚀 开始执行 PostgreSQL 迁移...')
const migrationsFolder = path.resolve(process.cwd(), 'packages/drizzle-pkg/migrations')
await migrate(db, {
migrationsFolder,
})
console.log('✅ PostgreSQL 迁移完成!')
} catch (err) {
console.log('❌ 迁移失败:', err)
throw err
} finally {
await pool.end()
}
}
const isMain =
process.argv[1] &&
path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)
if (isMain) {
runMigrations().catch((err) => {
console.error(err)
process.exit(1)
})
}

2
server/api/hello.ts

@ -6,7 +6,7 @@ const logger = log4js.getLogger("APP")
export default defineEventHandler(async (event) => { export default defineEventHandler(async (event) => {
logger.info("hello: world"); logger.info("hello: world");
const users = await dbGlobal.select().from(usersTable); const users = await dbGlobal.select().from(usersTable)
logger.info("users (formatted): %s \n", JSON.stringify(users, null, 2)); logger.info("users (formatted): %s \n", JSON.stringify(users, null, 2));
return { return {
hello: 'world', hello: 'world',

5
server/plugins/00.global.ts

@ -1,8 +1,5 @@
if (!import.meta.dev) { if (import.meta.dev) {
// 打包时需要保证migrator被引入
import('drizzle-orm/mysql2/migrator')
} else {
console.log("plugin: 00.global"); console.log("plugin: 00.global");
} }

Loading…
Cancel
Save