test: migration
This commit is contained in:
122
auto/migration /index.ts
Normal file
122
auto/migration /index.ts
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
import { NocoApi } from "../../src/index.ts";
|
||||||
|
|
||||||
|
type TableOptions = {
|
||||||
|
fromTableId: string;
|
||||||
|
fromNoco?: NocoApi;
|
||||||
|
toNoco?: NocoApi;
|
||||||
|
toBaseId?: string;
|
||||||
|
}
|
||||||
|
export class TableMigration {
|
||||||
|
fromTableId: string;
|
||||||
|
fromNoco: NocoApi;
|
||||||
|
toNoco: NocoApi;
|
||||||
|
toBaseId: string;
|
||||||
|
constructor(options: TableOptions) {
|
||||||
|
this.fromTableId = options.fromTableId;
|
||||||
|
this.fromNoco = options.fromNoco!;
|
||||||
|
this.toNoco = options.toNoco!;
|
||||||
|
this.toBaseId = options.toBaseId!;
|
||||||
|
}
|
||||||
|
async migrate() {
|
||||||
|
const res = await this.migrateTable();
|
||||||
|
console.log('migrate table result:', res);
|
||||||
|
this.toNoco.record.table = res.id;
|
||||||
|
this.fromNoco.record.table = this.fromTableId;
|
||||||
|
const fromTable = await this.fromNoco?.record.list({ limit: 2000 });
|
||||||
|
const list = fromTable?.data.list || [];
|
||||||
|
let _list = list.map(item => {
|
||||||
|
delete item['CreatedAt'];
|
||||||
|
delete item['UpdatedAt'];
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
console.log('_list', _list.length);
|
||||||
|
const newRecord = await this.toNoco.record.create(_list);
|
||||||
|
console.log('migrate success:', this.fromTableId);
|
||||||
|
}
|
||||||
|
async hasTable(title: string): Promise<{ id: string, exists?: boolean }> {
|
||||||
|
const res = await this.toNoco?.meta.tables.list(this.toBaseId);
|
||||||
|
const tables = res?.data?.list || [];
|
||||||
|
for (const table of tables) {
|
||||||
|
if (table.title === title) {
|
||||||
|
return { id: table.id, exists: true };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { id: '' };
|
||||||
|
}
|
||||||
|
async migrateTable() {
|
||||||
|
const res = await this.fromNoco?.meta.tables.getTableMeta(this.fromTableId);
|
||||||
|
const columns = res?.data.columns;
|
||||||
|
const title = res?.data.title;
|
||||||
|
const hasTableRes = await this.hasTable(title || '');
|
||||||
|
if (hasTableRes.id) {
|
||||||
|
return hasTableRes;
|
||||||
|
}
|
||||||
|
const clearCoulmns = ['nc_order', 'nc_created_by', 'nc_created_at', 'nc_updated_by', 'nc_updated_at', 'nc_owner_role', 'nc_owner_user', 'nc_status', 'CreatedAt', 'UpdatedAt'];
|
||||||
|
const _newColumns = [];
|
||||||
|
for (const col of columns || []) {
|
||||||
|
const createColData = {
|
||||||
|
title: col.title,
|
||||||
|
uidt: col.uidt,
|
||||||
|
description: col.description,
|
||||||
|
pk: col.pk,
|
||||||
|
pv: col.pv,
|
||||||
|
rqd: col.rqd,
|
||||||
|
cdf: col.cdf,
|
||||||
|
colOptions: col.colOptions,
|
||||||
|
};
|
||||||
|
if (clearCoulmns.includes(col.title)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
_newColumns.push(createColData);
|
||||||
|
}
|
||||||
|
const createRes = await this.toNoco.meta.tables.createTable(this.toBaseId, {
|
||||||
|
title: res?.data.title || 'Migrated Table',
|
||||||
|
description: res?.data.description || '',
|
||||||
|
columns: _newColumns,
|
||||||
|
});
|
||||||
|
return { id: createRes.data.id };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class BaseMigration {
|
||||||
|
fromBaseId: string;
|
||||||
|
toNoco: NocoApi;
|
||||||
|
toBaseId: string;
|
||||||
|
fromNoco: NocoApi;
|
||||||
|
constructor(options: { toNoco: NocoApi; toBaseId: string, fromNoco: NocoApi; fromBaseId: string }) {
|
||||||
|
this.toNoco = options.toNoco;
|
||||||
|
this.toBaseId = options.toBaseId;
|
||||||
|
this.fromNoco = options.fromNoco;
|
||||||
|
this.fromBaseId = options.fromBaseId;
|
||||||
|
}
|
||||||
|
async getTableList() {
|
||||||
|
const res = await this.fromNoco?.meta.tables.list(this.fromBaseId);
|
||||||
|
return res?.data?.list || [];
|
||||||
|
}
|
||||||
|
async migrate(options?: MigrateOptions) {
|
||||||
|
const tableList = await this.getTableList();
|
||||||
|
const excludeTables = options?.excludeTables || [];
|
||||||
|
const includeTables = options?.includeTables || [];
|
||||||
|
for (const table of tableList) {
|
||||||
|
if (excludeTables.includes(table.title || '')) {
|
||||||
|
console.log('skip table:', table.title);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (includeTables.length > 0 && !includeTables.includes(table.title || '')) {
|
||||||
|
console.log('skip table not in include list:', table.title);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const tableMigration = new TableMigration({
|
||||||
|
fromTableId: table.id,
|
||||||
|
fromNoco: this.fromNoco,
|
||||||
|
toNoco: this.toNoco,
|
||||||
|
toBaseId: this.toBaseId,
|
||||||
|
});
|
||||||
|
await tableMigration.migrate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
type MigrateOptions = {
|
||||||
|
excludeTables?: string[];
|
||||||
|
includeTables?: string[];
|
||||||
|
}
|
||||||
16
test/auto-common.ts
Normal file
16
test/auto-common.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import { NocoApi, } from './../src/main.ts';
|
||||||
|
import { useConfig } from '@kevisual/use-config'
|
||||||
|
export const config = useConfig()
|
||||||
|
import util from 'node:util';
|
||||||
|
|
||||||
|
export const nocoApi = new NocoApi({
|
||||||
|
baseURL: config.NOCODB_URL || 'http://localhost:8080',
|
||||||
|
token: config.NOCODB_API_KEY || '',
|
||||||
|
});
|
||||||
|
export const toNocoApi = new NocoApi({
|
||||||
|
baseURL: config.TO_NOCODB_URL || 'http://localhost:8080',
|
||||||
|
token: config.TO_NOCODB_API_KEY || '',
|
||||||
|
});
|
||||||
|
export const showMore = (obj: any) => {
|
||||||
|
return util.inspect(obj, { depth: null, colors: true });
|
||||||
|
}
|
||||||
35
test/migration.ts
Normal file
35
test/migration.ts
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import { TableMigration, BaseMigration } from "../auto/migration ";
|
||||||
|
|
||||||
|
import { nocoApi, toNocoApi } from "./auto-common";
|
||||||
|
|
||||||
|
const toBaseId = 'pjc9ks10ttrv6vz';
|
||||||
|
|
||||||
|
const baseId = 'p0np8adsoc79odk';
|
||||||
|
|
||||||
|
const tableId = 'mgt91mysuwts4e6';
|
||||||
|
|
||||||
|
async function migrateTable() {
|
||||||
|
const tableMigration = new TableMigration({
|
||||||
|
fromTableId: tableId,
|
||||||
|
fromNoco: nocoApi,
|
||||||
|
toNoco: toNocoApi,
|
||||||
|
toBaseId,
|
||||||
|
});
|
||||||
|
await tableMigration.migrate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// await migrateTable();
|
||||||
|
|
||||||
|
async function mirgtateBase() {
|
||||||
|
const baseMigration = new BaseMigration({
|
||||||
|
fromBaseId: baseId,
|
||||||
|
toBaseId,
|
||||||
|
fromNoco: nocoApi,
|
||||||
|
toNoco: toNocoApi,
|
||||||
|
});
|
||||||
|
await baseMigration.migrate({
|
||||||
|
excludeTables: ['控制中枢', '人生备忘录'],
|
||||||
|
// includeTables: ['人生备忘录']
|
||||||
|
});
|
||||||
|
}
|
||||||
|
mirgtateBase();
|
||||||
Reference in New Issue
Block a user