Skip to content

Importing .sql files

Load a script's MySQL dump without a MySQL server: drop it in tDB/sql/ and restart.

Scripts ship a .sql dump and expect you to load it into MySQL by hand. There is no MySQL here, so put the file in tDB/sql/ and restart instead.

txt
sql/
  01-qb-core.sql
  02-qb-inventory.sql
  03-my-shop.sql

Files run in filename order on startup, before tDB reports ready, so anything waiting on awaitConnection finds its tables already there. Number them only when one depends on another.

What to expect

  • A file runs once, ever. What has run is recorded in the tdb_sql_imports table.
  • A failure does not stop the server. The file, line and statement are reported, nothing is applied, and it is retried on the next restart.
  • A file edited after it ran is reported, not re-run.
  • A trigger tDB cannot translate is skipped, not fatal. The file still applies and the status becomes PARTIAL — see Skipped triggers.
  • mysqldump session noise is ignored: SET NAMES, LOCK TABLES, /*!40000 ALTER TABLE ... DISABLE KEYS */, START TRANSACTION and friends.

Changing a file after it has run

tDB tells you but will not re-run it, because replaying a dump replays its INSERTs. Config.Sql.OnChanged decides how loudly: "warn" and "error" differ only in log level and neither re-runs; "apply" re-runs it, which suits pure DDL dumps only.

To replay one file on demand:

txt
tdb sql import 01-qb-core.sql --force

Commands

Server console only. A player with the command.tdb ACE still gets nothing back.

CommandWhat it does
tdb sql statusEvery .sql file with its state: PENDING, or its recorded status (APPLIED, PARTIAL, FAILED) with statement count and duration. Flags files changed since they ran, and ledger rows whose file is gone
tdb sql import <file>Applies one file now. Refuses if it already ran or has changed
tdb sql import <file> --forceApplies it again regardless
tdb sql tables [match]Every table with its row count, optionally filtered by substring
tdb sql query <sql>Runs a read query and prints the rows, 50 at a time
tdb sql planWhich tables would be handed to PocketBase, and how each id is handled
tdb sql adoptHands them over now, after taking a backup

Where the imported data lives

Each imported table is handed to PocketBase as a base collection under its own name, browsable and editable in the admin UI. There is still one table, read and written by both SQL and the admin UI.

What changes when a table is adopted

  • id becomes TEXT. Existing values are preserved and an integer primary key keeps getting integers. WHERE id = ? matches whether you pass 5 or "5".
  • Nullable columns stay nullable, and WHERE col IS NULL keeps matching.
  • An edit in the admin UI cannot blank a NULL. Setting a real value works, but changing a NULL text field to an empty string through the UI leaves it NULL. Use UPDATE t SET col = '' WHERE ... for a literal empty string.
  • Foreign keys become triggers. ON DELETE CASCADE and ON DELETE SET NULL are re-created and fire for admin-UI deletes too. RESTRICT and NO ACTION cannot be reproduced and are reported.
  • INSERT INTO t VALUES (NULL, ...) stops working. Name your columns, or pass an id.

Rewritten triggers

Three MySQL trigger shapes are rewritten rather than refused:

MySQLBecomes
IF c THEN a; ELSE b; END IF;two triggers, each with a WHEN guard
DECLARE v; SELECT e INTO v; ... v ...a correlated subquery in place of the variable
UPDATE t JOIN u ON c SET aUPDATE t SET a FROM u WHERE c

A trigger with two DECLAREs, a reassigned variable, a nested IF or a two-table UPDATE is skipped rather than approximated.

Skipped triggers

A CREATE TRIGGER with no SQLite form is the one statement tDB drops rather than failing the file over. Every table and row still arrives; what stops happening is whatever the trigger maintained, usually a cached counter. Each is warned at import time, and tdb sql status lists them:

txt
PARTIAL   phone.sql  106 statement(s), 249ms - 6 trigger(s) skipped: ...

A PARTIAL file counts as applied and is not re-run. To add the triggers, rewrite them as SQLite in a second .sql file and drop that in too; the counter they maintained is recomputable with an UPDATE.

This is not Config.Migrations

Config.Migrations is PocketBase's own collection migration system, recording changes you make in the admin UI. The sql/ folder is for other people's MySQL dumps. The two never interact.

Still stuck? Support can answer it directly.

Was this page helpful?