Upgrade the Schema
Move a 1.x database from schema 1.0.0 to schema 2.0.0.
@dimah-s3/db 2.0 beta reads and writes schema 2.0.0. A database still at
1.0.0 throws on the first query, so upgrade it when you deploy the 2.0 beta.
For the code changes in every package, see
Upgrade to 2.0 beta.
What changes
metadatais renamed tos3_metadata. New columns:attributes,folder(NULLis the root), andupload_token.filenameis required. A missing one becomes the last segment of the key.statuscan also bepurging.- A new
storage_foldertable holds the folders. - The 1.x recommended indexes give way to the 2.0.0 indexes.
- SQLite: sizes become
INTEGER, and timestamps become epoch milliseconds. - MySQL: columns become
varcharanddatetime(3), and the table usesutf8mb4_bin, withutf8mb4_unicode_cionfilename.
Before you start
- Back up the database.
- Upgrade at a quiet time. An upload started on 1.x cannot confirm on the 2.0 beta, because the 2.0 beta confirms with an upload ticket.
- Do not let an ORM diff tool (
drizzle-kit,prisma migrate) write this upgrade. It can dropmetadatainstead of renaming it, and it cannot fill infilename.
Upgrade
Run the upgrade file for your database with your SQL tool:
psql "$DATABASE_URL" -f node_modules/@dimah-s3/db/sql/upgrade/1.0.0-2.0.0/pg.sql
# or sqlite.sql, mysql.sql in the same folder- The SQLite and PostgreSQL files run in one transaction.
- On MySQL, each
ALTER TABLEcommits on its own, so a failed step leaves the earlier ones applied. If you added the 1.x recommended indexes, drop them first: the statements are in the file header. Run it with the time zone your app connects with, since timestamps are converted in the session time zone. - The last statement sets the version in
private_dimah_s3_settings, which Kysely and Prisma read. With Drizzle, skip it (see below).
Use this path on SQLite and MySQL.
Update your ORM schema
The Drizzle adapter and tables need drizzle-orm 1.0.0-rc.5 or later;
0.44 and 0.45 are no longer supported. Upgrade drizzle-orm first.
Replace your generated 1.x schema file with the prebuilt tables
(setup), import the adapter from
@dimah-s3/db/adapters/drizzle, and remove fumadb and the fumadb/cuid
path alias from your app.
The 1.x settings table has id and version columns; the 2.0.0 definition
has key and value. The Drizzle adapter reads the version from the table
definition, not from the table, which is why you skip the last statement of
the SQL file. Let drizzle-kit update the settings table afterwards. It
holds nothing the adapter reads.
Check
Call checkSchema at startup. It throws unless the database is at
2.0.0:
await s3.db.checkSchema();Pending rows from 1.x have no upload token, so they can never confirm. Purge removes them. If their objects reached S3, purge keeps those, because they carry no upload marker: delete them yourself if you need the space.
Code changes
| 1.x | 2.0 beta |
|---|---|
fumadb/adapters/* | @dimah-s3/db/adapters/* |
resolveScope(request, context) | resolveScope({ request, locals, session, operation, … }) with getSession |
createObjectAccessGuard | authorize |
createQuotaGuard | quota as a function |
pendingTtlMs | removed: pending rows expire with the upload ticket |
purgeStalePendingObjects | s3.db.purgeStale() and s3.db.pruneDeleted() |
listByScope, countByScope, getScopeUsage | list, count, getUsage |
findActive, findByScopeKey, findPendingMultipart | find, then check the row |
dbObjectSource(api.db.listObjects, …) | dbObjectSource(api.db, { route, folders }) |
GET /db/objects?prefix=…&offset=… | ?folder=…&cursor=… |
QUOTA_EXCEEDED (413) | QUOTA_EXCEEDED (403) with params.limit |