Skip to content

Commit d5b65f2

Browse files
mabelsRomanNabukhotnyiAndriiSherman
authored
[drizzle-kit] push to d1-http failed (#4268)
* drizzle-kit and push to d1-http failed There are two reasons: - d1-http don't support transactions with db.run("begin/commit/rollback") - introspections run against some CF-D1 internal tables and fails later. that could mitigated with a right tablesFilter: ['!_cf_KV']. There was a incomplete mitigation in place which now includes _cf_KV tables. * chore: there are more _cf_ prefixed tables * fix: Add escaping to sqlite pull queries * should we pass-with-no-tests ?? * D P R I N T * Add ci vitest config * Bump kit, added release notes --------- Co-authored-by: Roman <[email protected]> Co-authored-by: AndriiSherman <[email protected]>
1 parent f39f885 commit d5b65f2

File tree

8 files changed

+111
-58
lines changed

8 files changed

+111
-58
lines changed

.github/workflows/release-feature-branch.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ jobs:
191191
192192
neon-serverless)
193193
docker compose -f docker-neon.yml up -d
194-
pnpm vitest run tests/pg/neon-serverless.test.ts
194+
pnpm vitest run --config=./vitest-ci.config.ts tests/pg/neon-serverless.test.ts
195195
docker compose -f docker-neon.yml down
196196
;;
197197

.github/workflows/release-latest.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,9 @@ jobs:
285285

286286
release:
287287
permissions: write-all
288+
needs:
289+
- test
290+
- attw
288291
strategy:
289292
fail-fast: false
290293
matrix:

changelogs/drizzle-kit/0.30.6.md

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
### Bug fixes
2+
3+
- [[BUG]: d1 push locally is not working](https://github.com/drizzle-team/drizzle-orm/issues/4099) - thanks @mabels and @RomanNabukhotnyi
4+
- [[BUG] Cloudflare D1: drizzle-kit push is not working (error 7500 SQLITE_AUTH)](https://github.com/drizzle-team/drizzle-orm/issues/3728) - thanks @mabels and @RomanNabukhotnyi

drizzle-kit/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "drizzle-kit",
3-
"version": "0.30.5",
3+
"version": "0.30.6",
44
"homepage": "https://orm.drizzle.team",
55
"keywords": [
66
"drizzle",

drizzle-kit/src/cli/commands/push.ts

+13-11
Original file line numberDiff line numberDiff line change
@@ -511,18 +511,20 @@ export const sqlitePush = async (
511511
if (statementsToExecute.length === 0) {
512512
render(`\n[${chalk.blue('i')}] No changes detected`);
513513
} else {
514-
if (!('driver' in credentials)) {
515-
await db.run('begin');
516-
try {
517-
for (const dStmnt of statementsToExecute) {
518-
await db.run(dStmnt);
519-
}
520-
await db.run('commit');
521-
} catch (e) {
522-
console.error(e);
523-
await db.run('rollback');
524-
process.exit(1);
514+
// D1-HTTP does not support transactions
515+
// there might a be a better way to fix this
516+
// in the db connection itself
517+
const isNotD1 = !('driver' in credentials && credentials.driver === 'd1-http');
518+
isNotD1 ?? await db.run('begin');
519+
try {
520+
for (const dStmnt of statementsToExecute) {
521+
await db.run(dStmnt);
525522
}
523+
isNotD1 ?? await db.run('commit');
524+
} catch (e) {
525+
console.error(e);
526+
isNotD1 ?? await db.run('rollback');
527+
process.exit(1);
526528
}
527529
render(`[${chalk.green('✓')}] Changes applied`);
528530
}

drizzle-kit/src/serializer/sqliteSerializer.ts

+66-44
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,18 @@ function extractGeneratedColumns(input: string): Record<string, ColumnInfo> {
495495
return columns;
496496
}
497497

498+
function filterIgnoredTablesByField(fieldName: string) {
499+
// _cf_ is a prefix for internal Cloudflare D1 tables (e.g. _cf_KV, _cf_METADATA)
500+
// _litestream_ is a prefix for internal Litestream tables (e.g. _litestream_seq, _litestream_lock)
501+
// libsql_ is a prefix for internal libSQL tables (e.g. libsql_wasm_func_table)
502+
// sqlite_ is a prefix for internal SQLite tables (e.g. sqlite_sequence, sqlite_stat1)
503+
return `${fieldName} != '__drizzle_migrations'
504+
AND ${fieldName} NOT LIKE '\\_cf\\_%' ESCAPE '\\'
505+
AND ${fieldName} NOT LIKE '\\_litestream\\_%' ESCAPE '\\'
506+
AND ${fieldName} NOT LIKE 'libsql\\_%' ESCAPE '\\'
507+
AND ${fieldName} NOT LIKE 'sqlite\\_%' ESCAPE '\\'`;
508+
}
509+
498510
export const fromDatabase = async (
499511
db: SQLiteDB,
500512
tablesFilter: (table: string) => boolean = (table) => true,
@@ -518,33 +530,30 @@ export const fromDatabase = async (
518530
hidden: number;
519531
sql: string;
520532
type: 'view' | 'table';
521-
}>(
522-
`SELECT
523-
m.name as "tableName", p.name as "columnName", p.type as "columnType", p."notnull" as "notNull", p.dflt_value as "defaultValue", p.pk as pk, p.hidden as hidden, m.sql, m.type as type
524-
FROM sqlite_master AS m JOIN pragma_table_xinfo(m.name) AS p
525-
WHERE (m.type = 'table' OR m.type = 'view')
526-
and m.tbl_name != 'sqlite_sequence'
527-
and m.tbl_name != 'sqlite_stat1'
528-
and m.tbl_name != '_litestream_seq'
529-
and m.tbl_name != '_litestream_lock'
530-
and m.tbl_name != 'libsql_wasm_func_table'
531-
and m.tbl_name != '__drizzle_migrations'
532-
and m.tbl_name != '_cf_KV';
533-
`,
534-
);
533+
}>(`SELECT
534+
m.name as "tableName",
535+
p.name as "columnName",
536+
p.type as "columnType",
537+
p."notnull" as "notNull",
538+
p.dflt_value as "defaultValue",
539+
p.pk as pk,
540+
p.hidden as hidden,
541+
m.sql,
542+
m.type as type
543+
FROM sqlite_master AS m
544+
JOIN pragma_table_xinfo(m.name) AS p
545+
WHERE (m.type = 'table' OR m.type = 'view')
546+
AND ${filterIgnoredTablesByField('m.tbl_name')};`);
535547

536548
const tablesWithSeq: string[] = [];
537549

538550
const seq = await db.query<{
539551
name: string;
540-
}>(
541-
`SELECT * FROM sqlite_master WHERE name != 'sqlite_sequence'
542-
and name != 'sqlite_stat1'
543-
and name != '_litestream_seq'
544-
and name != '_litestream_lock'
545-
and tbl_name != '_cf_KV'
546-
and sql GLOB '*[ *' || CHAR(9) || CHAR(10) || CHAR(13) || ']AUTOINCREMENT[^'']*';`,
547-
);
552+
}>(`SELECT
553+
*
554+
FROM sqlite_master
555+
WHERE sql GLOB '*[ *' || CHAR(9) || CHAR(10) || CHAR(13) || ']AUTOINCREMENT[^'']*'
556+
AND ${filterIgnoredTablesByField('tbl_name')};`);
548557

549558
for (const s of seq) {
550559
tablesWithSeq.push(s.name);
@@ -685,11 +694,19 @@ export const fromDatabase = async (
685694
onDelete: string;
686695
seq: number;
687696
id: number;
688-
}>(
689-
`SELECT m.name as "tableFrom", f.id as "id", f."table" as "tableTo", f."from", f."to", f."on_update" as "onUpdate", f."on_delete" as "onDelete", f.seq as "seq"
690-
FROM sqlite_master m, pragma_foreign_key_list(m.name) as f
691-
where m.tbl_name != '_cf_KV';`,
692-
);
697+
}>(`SELECT
698+
m.name as "tableFrom",
699+
f.id as "id",
700+
f."table" as "tableTo",
701+
f."from",
702+
f."to",
703+
f."on_update" as "onUpdate",
704+
f."on_delete" as "onDelete",
705+
f.seq as "seq"
706+
FROM
707+
sqlite_master m,
708+
pragma_foreign_key_list(m.name) as f
709+
WHERE ${filterIgnoredTablesByField('m.tbl_name')};`);
693710

694711
const fkByTableName: Record<string, ForeignKey> = {};
695712

@@ -752,21 +769,20 @@ export const fromDatabase = async (
752769
columnName: string;
753770
isUnique: number;
754771
seq: string;
755-
}>(
756-
`SELECT
757-
m.tbl_name as tableName,
758-
il.name as indexName,
759-
ii.name as columnName,
760-
il.[unique] as isUnique,
761-
il.seq as seq
762-
FROM sqlite_master AS m,
763-
pragma_index_list(m.name) AS il,
764-
pragma_index_info(il.name) AS ii
765-
WHERE
766-
m.type = 'table'
767-
and il.name NOT LIKE 'sqlite_autoindex_%'
768-
and m.tbl_name != '_cf_KV';`,
769-
);
772+
}>(`SELECT
773+
m.tbl_name as tableName,
774+
il.name as indexName,
775+
ii.name as columnName,
776+
il.[unique] as isUnique,
777+
il.seq as seq
778+
FROM
779+
sqlite_master AS m,
780+
pragma_index_list(m.name) AS il,
781+
pragma_index_info(il.name) AS ii
782+
WHERE
783+
m.type = 'table'
784+
AND il.name NOT LIKE 'sqlite\\_autoindex\\_%' ESCAPE '\\'
785+
AND ${filterIgnoredTablesByField('m.tbl_name')};`);
770786

771787
for (const idxRow of idxs) {
772788
const tableName = idxRow.tableName;
@@ -862,9 +878,15 @@ WHERE
862878
const unnamedCheckPattern = /CHECK\s*\((.*?)\)/gi;
863879
let checkCounter = 0;
864880
const checkConstraints: Record<string, CheckConstraint> = {};
865-
const checks = await db.query<{ tableName: string; sql: string }>(`SELECT name as "tableName", sql as "sql"
881+
const checks = await db.query<{
882+
tableName: string;
883+
sql: string;
884+
}>(`SELECT
885+
name as "tableName",
886+
sql as "sql"
866887
FROM sqlite_master
867-
WHERE type = 'table' AND name != 'sqlite_sequence';`);
888+
WHERE type = 'table'
889+
AND ${filterIgnoredTablesByField('tbl_name')};`);
868890
for (const check of checks) {
869891
if (!tablesFilter(check.tableName)) continue;
870892

integration-tests/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"scripts": {
77
"test:types": "tsc",
88
"test": "pnpm test:vitest",
9-
"test:vitest": "vitest run",
9+
"test:vitest": "vitest run --pass-with-no-tests",
1010
"test:esm": "node tests/imports.test.mjs && node tests/imports.test.cjs",
1111
"test:data-api": "sst shell vitest run tests/pg/awsdatapi.test.ts"
1212
},

integration-tests/vitest-ci.config.ts

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import 'dotenv/config';
2+
import tsconfigPaths from 'vite-tsconfig-paths';
3+
import { defineConfig } from 'vitest/config';
4+
5+
export default defineConfig({
6+
test: {
7+
typecheck: {
8+
tsconfig: 'tsconfig.json',
9+
},
10+
testTimeout: 100000,
11+
hookTimeout: 200000,
12+
isolate: true,
13+
poolOptions: {
14+
threads: {
15+
singleThread: true,
16+
},
17+
},
18+
maxWorkers: 1,
19+
fileParallelism: false,
20+
},
21+
plugins: [tsconfigPaths()],
22+
});

0 commit comments

Comments
 (0)