fix: migration error (#6470)

* fix: migration error

* fix: test case

* fix(plugin-workflow-manual): fix migration

* fix(plugin-workflow-manual): remove useless code

* test(plugin-workflow-manual): add more case

---------

Co-authored-by: mytharcher <mytharcher@gmail.com>
This commit is contained in:
chenos 2025-03-15 23:37:46 +08:00 committed by GitHub
parent e1f7e94e0d
commit fd7c839228
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 167 additions and 12 deletions

View File

@ -10,7 +10,7 @@
import { createMockServer } from '@nocobase/test';
import { describe, test } from 'vitest';
import workflowManualTasks from '../../collections/workflowManualTasks';
import Migration from '../../migrations/20250312100512-change-table-name';
import Migration from '../../migrations/20250312100513-change-table-name';
const skipSqlite = process.env.DB_DIALECT === 'sqlite' ? test.skip : test;
@ -86,11 +86,6 @@ describe('20250225175712-change-table-name.test', () => {
skipSqlite(`multiple primary keys`, async () => {
const app = await createMockServer();
await app.version.update('1.5.0');
// mock m2m collections
app.db.collection({
...workflowManualTasks,
name: 'users_jobs',
});
app.db.collection({
name: 'users',
fields: [{ name: 'id', type: 'bigInt', primaryKey: true }],
@ -128,4 +123,152 @@ describe('20250225175712-change-table-name.test', () => {
await app.destroy();
});
skipSqlite(`legacy multiple primary keys (without id)`, async () => {
const app = await createMockServer();
await app.version.update('1.5.0');
app.db.collection({
name: 'users',
fields: [
{ name: 'id', type: 'bigInt', primaryKey: true },
{
type: 'belongsToMany',
name: 'jobs',
through: 'users_jobs',
},
],
});
app.db.collection({
name: 'jobs',
fields: [
{ name: 'id', type: 'bigInt', primaryKey: true },
{
type: 'belongsToMany',
name: 'users',
through: 'users_jobs',
},
],
});
app.db.collection({
name: 'users_jobs',
fields: [
{
type: 'belongsTo',
name: 'job',
target: 'jobs',
foreignKey: 'jobId',
primaryKey: true,
},
{
type: 'belongsTo',
name: 'user',
target: 'users',
foreignKey: 'userId',
primaryKey: true,
},
],
});
await app.db.sync();
const migration = new Migration({ db: app.db, app } as any);
await migration.up();
app.db.collection({
...workflowManualTasks,
});
app.db.removeCollection('jobs');
app.db.collection({
name: 'jobs',
fields: [{ name: 'id', type: 'bigInt', primaryKey: true }],
});
await app.db.sync();
const columns = await app.db.sequelize
.getQueryInterface()
.describeTable(app.db.getCollection(workflowManualTasks.name).getTableNameWithSchema());
const primaryKeys = Object.keys(columns).filter((c) => columns[c].primaryKey);
expect(primaryKeys.length).toBe(1);
expect(primaryKeys[0]).toBe('id');
await app.destroy();
});
skipSqlite(`width id as primary key`, async () => {
const app = await createMockServer();
await app.version.update('1.5.0');
app.db.collection({
name: 'users_jobs',
fields: [
{
type: 'bigInt',
name: 'id',
primaryKey: true,
autoIncrement: true,
},
{
type: 'belongsTo',
name: 'job',
target: 'jobs',
foreignKey: 'jobId',
primaryKey: false,
},
{
type: 'belongsTo',
name: 'user',
target: 'users',
foreignKey: 'userId',
primaryKey: false,
},
],
});
app.db.collection({
name: 'users',
fields: [
{ name: 'id', type: 'bigInt', primaryKey: true },
{
type: 'belongsToMany',
name: 'jobs',
through: 'users_jobs',
},
],
});
app.db.collection({
name: 'jobs',
fields: [
{ name: 'id', type: 'bigInt', primaryKey: true },
{
type: 'belongsToMany',
name: 'users',
through: 'users_jobs',
},
],
});
await app.db.sync();
const migration = new Migration({ db: app.db, app } as any);
await migration.up();
app.db.collection({
...workflowManualTasks,
});
app.db.removeCollection('jobs');
app.db.collection({
name: 'jobs',
fields: [{ name: 'id', type: 'bigInt', primaryKey: true }],
});
await app.db.sync();
const columns = await app.db.sequelize
.getQueryInterface()
.describeTable(app.db.getCollection(workflowManualTasks.name).getTableNameWithSchema());
const primaryKeys = Object.keys(columns).filter((c) => columns[c].primaryKey);
expect(primaryKeys.length).toBe(1);
expect(primaryKeys[0]).toBe('id');
await app.destroy();
});
});

View File

@ -7,8 +7,8 @@
* For more information, please refer to: https://www.nocobase.com/agreement.
*/
import { Transaction } from 'sequelize';
import { Migration } from '@nocobase/server';
import { Transaction } from 'sequelize';
import workflowManualTasks from '../collections/workflowManualTasks';
export default class extends Migration {
@ -88,9 +88,23 @@ export default class extends Migration {
}
}
} else if (this.db.isMySQLCompatibleDialect()) {
await db.sequelize.query(`ALTER TABLE ${newTableNameWithQuotes} DROP PRIMARY KEY, ADD PRIMARY KEY (id)`, {
transaction,
});
const idExists = await workflowManualTasksCollection.getField('id').existsInDb();
if (!idExists) {
await db.sequelize.query(`ALTER TABLE ${newTableNameWithQuotes} ADD COLUMN id BIGINT;`, {
transaction,
});
await db.sequelize.query(`ALTER TABLE ${newTableNameWithQuotes} DROP PRIMARY KEY`, {
transaction,
});
await db.sequelize.query(`ALTER TABLE ${newTableNameWithQuotes} ADD PRIMARY KEY (id)`, {
transaction,
});
await db.sequelize.query(`ALTER TABLE ${newTableNameWithQuotes} MODIFY COLUMN id BIGINT AUTO_INCREMENT`, {
transaction,
});
} else {
console.log('------------------ id exists', idExists);
}
}
const indexes: any = await queryInterface.showIndex(newTableName, { transaction });

View File

@ -31,8 +31,6 @@ export default class extends Migration {
},
transaction,
});
db.removeCollection('fields');
});
}
}