Skip to main content

Model Management

The model.load() method is the primary way to sync dimension table structure and data from external sources into Farseer.

Basic Usage

import { ModelTableColumnType } from 'farseer-client';

await client.model.load({
model: {
tables: [{
name: 'Product',
columns: [
{ name: 'Name', type: ModelTableColumnType.PrimaryKey },
{ name: 'Description', type: ModelTableColumnType.Description },
{ name: 'Category', type: ModelTableColumnType.ForeignKey, foreignKeyTableName: 'Category' }
],
rows: [
['Product A', 'Description A', 'Electronics'],
['Product B', 'Description B', 'Furniture']
]
}],
variables: [],
dependencies: { tables: [], members: [], variables: [] }
},
options: {
clear: false,
deleteEnabled: { rows: false, tables: false, variables: false, columns: false, cells: false },
dryRun: false
}
});

Column Types

TypePurposeExample
PrimaryKeyUnique identifier for the memberProduct name
DescriptionDisplay descriptionProduct details
ForeignKeyReference to another dimension tableCategory
FormulaCalculated expressionsum(...)
NumberNumeric propertyPrice
TextText propertyNotes
DateDate propertyCreated date

Options

OptionTypeDescription
clearbooleanClear existing data before loading
dryRunbooleanPreview changes without applying
deleteEnabled.rowsbooleanAllow deleting dimension members
deleteEnabled.tablesbooleanAllow deleting dimension tables
deleteEnabled.variablesbooleanAllow deleting variables
deleteEnabled.columnsbooleanAllow deleting columns
deleteEnabled.cellsbooleanAllow deleting cell data
tip

Use dryRun: true during development to preview what changes would be made without actually applying them.


Syncing Multiple Tables

Use data.syncMultipleTables() for a simplified interface when syncing Arquero tables:

await client.data.syncMultipleTables([
{
name: 'Products',
columns: [
{ name: 'Name', type: 'PrimaryKey' },
{ name: 'Category', type: 'ForeignKey', foreignKeyTableName: 'Categories' }
],
rows: productTable // Arquero table
},
{
name: 'Categories',
columns: [
{ name: 'Name', type: 'PrimaryKey' },
{ name: 'Description', type: 'Description' }
],
rows: categoryTable
}
]);

Batch Processing for Large Datasets

For large datasets, process in batches to avoid memory and timeout issues:

const allRows = [...]; // e.g., 10,000 dimension members
const batchSize = 5000;

for (let i = 0; i < allRows.length; i += batchSize) {
const batchRows = allRows.slice(i, i + batchSize);

await client.model.load({
model: {
tables: [{
name: 'Product',
columns: [
{ name: 'Name', type: ModelTableColumnType.PrimaryKey },
{ name: 'Description', type: ModelTableColumnType.Description },
],
rows: batchRows
}],
variables: [],
dependencies: { tables: [], members: [], variables: [] }
},
options: {
clear: i === 0, // Only clear on first batch
deleteEnabled: { rows: false, tables: false, variables: false, columns: false, cells: false },
dryRun: false
}
});

console.log(`Synced ${Math.min(i + batchSize, allRows.length)} / ${allRows.length} members`);
}

SQL Server to Farseer Sync

A common real-world pattern: read from SQL Server and sync to Farseer.

import * as mssql from 'mssql';
import * as farseer from 'farseer-client';

const client = new farseer.FarseerClient();
const pool = await mssql.connect({
user: 'username',
password: 'password',
server: 'server',
database: 'database',
});

// Query data
const data = await client.data.mssqlQuery(pool, `
SELECT * FROM [dbo].[Products]
WHERE Active = 1
`);

// Select relevant columns and sync
const brickData = data.select('RegionId', 'AreaId');

await client.data.syncMultipleTables([
{
name: 'Brick',
columns: [
{ name: 'regionId', type: farseer.ModelTableColumnType.PrimaryKey },
{ name: 'areaId', type: farseer.ModelTableColumnType.ForeignKey, foreignKeyTableName: 'Area' },
],
rows: brickData,
}
]);

await pool.close();