This functionality only works with data models written in JavaScript, not YAML.For similar functionality in YAML, see Dynamic data models with Jinja and Python.
asyncModule() function only available in the
execution environment. asyncModule() allows registering an
async function to be executed at the end of the data model compile phase so
additional definitions can be added. This is often useful in situations where
data model properties can be dynamically updated through an API, for example.
When creating data models via asyncModule(), it is important to be aware of
the following differences compared to statically defined ones with cube():
- The
sqlanddrill_membersproperties for both dimensions and measures must be of type() => stringand() => string[]accordingly
Generation
In the following example, we retrieve a JSON object representing all our cubes usingfetch(), transform some of the properties to be functions that return a
string, and then finally use the cube() global function to
generate data models from that data:
Caching with memo
memo(key, fn) calls fn only the first time a key is seen during a data
model compilation and returns its result, the same promise for an async fn,
on every later call, in every stage and from every data model file. key is a
string or a JSON-serializable value, such as an array. Results are not shared
between compilations, so each recompilation, e.g., after a
schema_version change, fetches fresh data:
memo(fn) gets a key made of the file name and the
position of the call, so each call site is cached on its own:
memo(["columns", table], fn). A keyless memo(fn) that runs
more than once per compilation stage is an error.
The function passed to memo() should only fetch and return data. Calling
cube(), view(), context(), view_group() or asyncModule() from it is an error, as the
function doesn’t run again in later compilation stages. Define the model objects
from the returned data outside of memo(), as in the example above. Every
stage gets the same returned object, so don’t mutate it or pass it to cube()
as is: build new definitions from it instead.
Usage with schema_version
It is also useful to be able to recompile the data model when there are changes
in the underlying input data. For this purpose, the schema_version
value in the cube.js configuration options can
be specified as an asynchronous function:
Usage with COMPILE_CONTEXT
TheCOMPILE_CONTEXT global object can also be used in conjunction with async
data model creation to allow for multi-tenant deployments of Cube.
In an example scenario where all tenants share the same cube, but see different
dimensions and measures, you could do the following:
Usage with data_source
When using multiple databases, you’ll need to ensure you set thedata_source property for any asynchronously-created
data models, as well as ensuring the corresponding database drivers are set up with
driverFactory() in your cube.js configuration
file.
For an example scenario where data models may use either MySQL or Postgres
databases, you could do the following: