typeorm/typeorm · error · TypeORMError
Rename table queries are not supported by Spanner driver.
Error message
Rename table queries are not supported by Spanner driver.
What it means
TypeORMError thrown unconditionally by renameTable(). Spanner DDL has no ALTER TABLE ... RENAME TO statement, so renaming a table is not possible in place; the driver refuses rather than emitting invalid DDL.
Source
Thrown at src/driver/spanner/SpannerQueryRunner.ts:816
const downQueries: Query[] = []
upQueries.push(await this.deleteViewDefinitionSql(view))
upQueries.push(this.dropViewSql(view))
downQueries.push(await this.insertViewDefinitionSql(view))
downQueries.push(this.createViewSql(view))
await this.executeQueries(upQueries, downQueries)
}
/**
* Renames the given table.
*
* @param oldTableOrName
* @param newTableName
*/
async renameTable(
oldTableOrName: Table | string,
newTableName: string,
): Promise<void> {
throw new TypeORMError(
`Rename table queries are not supported by Spanner driver.`,
)
}
/**
* Creates a new column from the column in the table.
*
* @param tableOrName
* @param column
*/
async addColumn(
tableOrName: Table | string,
column: TableColumn,
): Promise<void> {
const table =
tableOrName instanceof Table
? tableOrName
: await this.getCachedTable(tableOrName)View on GitHub (pinned to 04ff4daedc)
Solutions
- Replace the rename with an explicit CREATE TABLE new ... + copy data + DROP TABLE old, executed as DDL via updateDDL.
- Generate the migration manually rather than relying on renameTable.
- Keep table names stable; rename via a new table and a backfill/cutover.
Example fix
// before
await qr.renameTable("old_users", "users");
// after
await qr.updateDDL(`CREATE TABLE users (... ) PRIMARY KEY (id)`);
// copy rows, then:
await qr.updateDDL(`DROP TABLE old_users`); Defensive patterns
Strategy: try-catch
Validate before calling
async function safeRenameTable(qr: QueryRunner, oldName: string, newName: string, buildNewDdl: string): Promise<void> {
if ((qr.driver.options as any).type === "spanner") {
await qr.updateDDL(buildNewDdl);
// copy data, then drop old
} else {
await qr.renameTable(oldName, newName);
}
} Type guard
function supportsRenameTable(ds: DataSource): boolean {
return (ds.options as any).type !== "spanner";
} Try / catch
try {
await qr.renameTable(oldName, newName);
} catch (e) {
if (/Rename table queries are not supported by Spanner/i.test(String(e?.message ?? e))) {
// fall through to create+copy+drop strategy
return;
}
throw e;
} Prevention
- Avoid generated renames; keep table names stable on Spanner.
- Convert rename migrations to create+copy+drop for Spanner targets.
- Write migrations explicitly rather than relying on renameTable.
When it happens
Trigger: Calling queryRunner.renameTable(old, new); migrations generated from entity renames that translate to renameTable.
Common situations: Renaming an entity and letting the migration generator emit a rename; cross-driver migration scripts that assume rename support.
Related errors
- Check database queries are not supported by Spanner driver.
- Check schema queries are not supported by Spanner driver.
- The keys of a table can't change; you can't add a key column
- Spanner does not support unique constraints. Use unique inde
- Schema create queries are not supported by MySql driver.
AI-assisted analysis of typeorm/typeorm@04ff4daedc (2026-08-03).
Data as JSON: /data/errors/ab128a9f538c6903.json.
Report an issue: GitHub.