-
- Notifications
You must be signed in to change notification settings - Fork 2
ALTER TABLE
See APIS ➞
client.query(),database.alterTable()
See related ➞ ALTER DATABASE ➞
Manage Tables
Rename table:
// (a): SQL syntax await client.query( `ALTER TABLE database_1.table_1 RENAME TO table_1_new`, { desc: 'Alter description' } );// (b): Function-based syntax const table = await client.database('database_1').alterTable( 'table_1', (schema) => schema.name('table_1_new'), { desc: 'Alter description' } );Note
While the default function-based syntax may read "alter table", you can imply the "view" kind by setting options.kind === 'view':
client.alterTable(..., { desc: 'Alter description', kind: 'view' });Alter with an EXISTS check (PostgreSQL):
// (a): SQL syntax await client.query( `ALTER TABLE IF EXISTS database_1.table_1 RENAME TO table_1_new`, { desc: 'Alter description' } );// (b): Function-based syntax const table = await client.database('database_1').alterTable( 'table_1', (schema) => schema.name('table_1_new'), { desc: 'Alter description', ifExists: true } );Alter deeply:
// Function-based syntax const table = await client.database('database_1').alterTable( 'table_1', (schema) => { schema.name('table_1_new'); schema.column('col_1').name('col_1_new'); schema.constraint('constraint_1').name('constraint_1_new'); }, { desc: 'Alter description' } );Tip
The equivalent SQL syntax via client.query() would otherwise be:
.query('ALTER TABLE... RENAME ...').query('ALTER TABLE... RENAME COLUMN ..., RENAME CONSTRAINT ...')
See related ➞
ALTER COLUMN
Add columns:
// (a): SQL syntax await client.query( `ALTER TABLE database_1.table_1 ADD col_3 varchar UNIQUE, ADD COLUMN col_4 varchar`, { desc: 'Alter description' } );// (b): Function-based syntax const table = await client.database('database_1').alterTable( 'table_1', (schema) => { schema.column({ name: 'col_3', type: 'varchar', uniqueKey: true }); schema.column({ name: 'col_4', type: 'varchar' }); }, { desc: 'Alter description' } );Note
Where the column implied by name already exists, the column is modified with the diff between the existing schema and the new schema.
Drop columns:
// (a): SQL syntax await client.query( `ALTER TABLE database_1.table_1 DROP col_3, DROP COLUMN col_4`, { desc: 'Alter description' } );// (b): Function-based syntax const table = await client.database('database_1').alterTable( 'table_1', (schema) => { schema.column('col_3', false); schema.column('col_4', false); }, { desc: 'Alter description' } );Tip
PostgreSQL:
To add a CASCADE or RESTRICT flag to each DROP COLUMN operation, use options.cascadeRule.
database.alterTable(..., { desc: 'Alter description', cascadeRule: 'CASCADE' });See related ➞
ALTER CONSTRAINT
Add constraints (auto-named):
// (a): SQL syntax await client.query( `ALTER TABLE database_1.table_1 ADD CONSTRAINT PRIMARY KEY (col_1), ADD CONSTRAINT FOREIGN KEY (col_2) REFERENCES database_1.table_2 (col_1), ADD CONSTRAINT UNIQUE (col_3), ADD CONSTRAINT CHECK (col_4 > 2)`, { desc: 'Alter description' } );// (b): Function-based syntax 1 const table = await client.database('database_1').alterTable( 'table_1', (schema) => { schema.column('col_1').primaryKey(true); schema.column('col_2').foreignKey({ targetTable: ['database_1', 'table_2'], targetColumns: ['col_1'] }); schema.column('col_3').uniqueKey(true); schema.column('col_4').check({ expr: { greaterThan: ['col_4', 4] } }); }, { desc: 'Alter description' } );// (c): Function-based syntax 2 const table = await client.database('database_1').alterTable( 'table_1', (schema) => { schema.constraint({ type: 'PRIMARY_KEY', columns: ['col_1'] }); schema.constraint({ type: 'FOREIGN_KEY', columns: ['col_2'], targetTable: ['database_1', 'table_2'], targetColumns: ['col_1'] }); schema.constraint({ type: 'UNIQUE_KEY', columns: ['col_3'] }); schema.constraint({ type: 'CHECK', expr: { greaterThan: ['col_4', 4] } }); }, { desc: 'Alter description' } );Note
Where the constraint implied by name already exists, the constraint is modified with the diff between the existing schema and the new schema.
Note
While single-column constraints may be defined at the table level, they are moved into their respective columns under the hood by Linked QL. This gives us a consistent way to access a constraint whether defined via syntax (b) or syntax (c):
const checkConstraint = schema.column('col_4').check(); const fkConstraint = schema.column('col_2').foreignKey();Yet, these can always be accessed by name at the table level:
const checkConstraint = schema.constraint(constraintName); const fkConstraint = schema.constraint(constraintName);Note
In all cases above, each constraint is automatically assigned a random name by Linked QL; useful for when they need to be accessed subsequently.
Add constraints (explicitly-named, recommended):
// (a): SQL syntax await client.query( `ALTER TABLE database_1.table_1 ADD CONSTRAINT constraint_1 PRIMARY KEY (col_1), ADD CONSTRAINT constraint_2 FOREIGN KEY (col_2) REFERENCES database_1.table_2 (col_1), ADD CONSTRAINT constraint_3 UNIQUE (col_3), ADD CONSTRAINT constraint_4 CHECK (col_4 > 2)`, { desc: 'Alter description' } );// (b): Function-based syntax 1 const table = await client.database('database_1').alterTable( 'table_1', (schema) => { schema.column('col_1').primaryKey({ name: 'constraint_1', }); schema.column('col_2').foreignKey({ targetTable: ['database_1', 'table_2'], targetColumns: ['col_1'], name: 'constraint_2' }); schema.column('col_3').uniqueKey({ name: 'constraint_3' }); schema.column('col_4').check({ expr: { greaterThan: ['col_4', 4] }, name: 'constraint_4' }); }, { desc: 'Alter description' } );// (c): Function-based syntax 2 const table = await client.database('database_1').alterTable( 'table_1', (schema) => { schema.constraint({ type: 'PRIMARY_KEY', columns: ['col_1'], name: 'constraint_1' }); schema.constraint({ type: 'FOREIGN_KEY', columns: ['col_2'], targetTable: ['database_1', 'table_2'], targetColumns: ['col_1'], name: 'constraint_2' }); schema.constraint({ type: 'UNIQUE_KEY', columns: ['col_3'], name: 'constraint_3' }); schema.constraint({ type: 'CHECK', expr: { greaterThan: ['col_4', 4] }, name: 'constraint_4' }); }, { desc: 'Alter description' } );Note
As before, while single-column constraints may be defined at the table level, they are moved into their respective columns under the hood by Linked QL. This gives us a consistent way to access a constraint whether defined via syntax (b) or syntax (c):
const checkConstraint = schema.column('col_4').check(); const fkConstraint = schema.column('col_2').foreignKey();Yet, these can always be accessed by name at the table level:
const checkConstraint = schema.constraint('constraint_2'); const fkConstraint = schema.constraint('constraint_4');Add constraints (multi-column):
// (a): SQL syntax await client.query( `ALTER TABLE database_1.table_1 ADD CONSTRAINT constraint_1 PRIMARY KEY (col_1, col_2), ADD CONSTRAINT constraint_2 FOREIGN KEY (col_2, col_3) REFERENCES database_1.table_2 (col_1, col_2), ADD CONSTRAINT constraint_3 UNIQUE (col_3, col_4), ADD CONSTRAINT constraint_4 CHECK (col_4 > col_5)`, { desc: 'Alter description' } );// (c): Function-based syntax const table = await client.database('database_1').alterTable( 'table_1', (schema) => { schema.constraint({ type: 'PRIMARY_KEY', columns: ['col_1', 'col_2'], name: 'constraint_1' }); schema.constraint({ type: 'FOREIGN_KEY', columns: ['col_2', 'col_3'], targetTable: ['database_1', 'table_2'], targetColumns: ['col_1', 'col_2'], name: 'constraint_2' }); schema.constraint({ type: 'UNIQUE_KEY', columns: ['col_3', 'col_4'], name: 'constraint_3' }); schema.constraint({ type: 'CHECK', expr: { greaterThan: ['col_4', 'col_5'] }, name: 'constraint_4' }); }, { desc: 'Alter description' } );Note
As before, where the constraint implied by name already exists, the constraint is modified with the diff between the existing schema and the new schema.
Note
Multi-column constraints can only be defined as above: at the table level.
Drop constraints:
// (a): SQL syntax await client.query( `ALTER TABLE database_1.table_1 DROP CONSTRAINT constraint_4`, { desc: 'Alter description' } );// (b): Function-based syntax const table = await client.database('database_1').alterTable( 'table_1', (schema) => { schema.constraint('constraint_4', false); }, { desc: 'Alter description' } );Tip
PostgreSQL:
To add a CASCADE or RESTRICT flag to each DROP CONSTRAINT operation, use options.cascadeRule.
database.alterTable(..., { desc: 'Alter description', cascadeRule: 'CASCADE' });Manage Constraints (fine-grained):
// Function-based syntax const table = await client.database('database_1').alterTable( 'table_1', (schema) => { // Rename primary key schema.column('col_1').primaryKey().name('pk_1_new'); // Change a foreign key's "targetTable" and "targetColumn" references schema.column('col_2').foreignKey() .targetTable(['database_1', 'table_10']) .columns('col_30'); // Change a constraint's "columns" list schema.constraint('constraint_1').columns(['col_1', 'col_2', 'col_3']); // Change a check constraint's expression schema.column('col_4').check().expr({ greaterThan: ['col_4', 40] }); }, { desc: 'Alter description' } );Tip
This granular level of modification is acheived in SQL by dropping and recreating the respective constraints, and the equivalent SQL syntax via client.query() otherwise would be:
.query('ALTER TABLE... DROP CONSTRAINT constraint_1').query('ALTER TABLE... ADD CONSTRAINT constraint_1...')
Return the resulting table schema:
// (a): SQL syntax const schema = await client.query( `ALTER TABLE database_1.table_1 RENAME TO table_1_new RETURNING SCHEMA`, { desc: 'Alter description' } );// (b): Function-based syntax const schema = await database.alterTable( 'table_1', (schema) => { schema.name('table_1_new'); }, { desc: 'Alter description', returning: 'schema' } );See related ➞
table.schema()
Return the associated savepoint instance:
// (a): SQL syntax const savepoint = await client.query( `ALTER TABLE database_1.table_1 RENAME TO table_1_new RETURNING SAVEPOINT`, { desc: 'Alter description' } );// (b): Function-based syntax const savepoint = await database.alterTable( 'table_1', (schema) => { schema.name('table_1_new'); }, { desc: 'Alter description', returning: 'savepoint' } );See related ➞
database.savepoint()