Tutorial

The imagine compiler generates code from spec files where the user can indicate different project settings and datamodel specifications. Each spec file can contain a first section with project settings and a second section with datamodel spec.

Project settingsProject settings are written in yaml format:

config
app-name: <appname>
database-name: <dbname>
framework: <frameworkname>
<frameworkname>-settings:
<setting-1>: <value-1>
...
<setting-n>: <value-n>
<setting-list>:
- <listvalue-1>
...
- <listvalue-n>
<setting-tree-root>:
<setting-branch-1>:
...
<setting-branch-n>:
...
end config

A default project settings is created when the user runs imagine create command, with default values for the specified framework.

Datamodel spec

Datamodel specification is written according to the following syntax, where each model is specified indicating an identifier (a string starting with a leter, followed by any number of letters, numbers or '), a primary key and a list of fields:

Model <identifier>:
PrimKey <identifier> <fieldtype> [x_1, ..., x_n0]
Field <identifier> <fieldtype> [y_1, ..., y_n1]
....

Each field must have a <fieldtype>, which can be either Int, Str or Datetime. Each field must have a list (possibly empty) of options and constraints.

The supported options are: - default <val> where <val> is the default value for the field.

The supported constraints are - unique - nullable - maxlength <int> - range <int> <int> - choice [x_1, ..., x_n]

Many-to-one and many-to-many relations are specified in this way:

Relation ManyToOne <modelname> as <identifier> <modelname> as <identifier>
Relation ManyToOne <modelname> as <identifier> <modelname> as <identifier> ForeignKey <identifier>
Relation ManyToMany <modelname> as <identifier> <modelname> as <identifier>

the references (as <identifier>) are the names of the relation in each model. For instance, Relation ManyToOne Model0 as ref0 Model1 as ref1 means that the model Model0 has a field ref0 which is an instance of Model1, and Model0 has a filed ref1 which is a collection of instances of Model0. Reference identifiers can't clash with model fields. In the second example, we specify the foreign key for the relation, and the identifier must reference a unique field.

Example

# Imagine spec file
# Text between # and end of line is discarded
# spaces, tabs and newlines outside the config section are ignored
config
app-name: music
database-name: db.sqlite3
framework: django
django-settings:
service-name: service
models: models
serializers: serializers
views: views
urls: urls
end config
Model Musician: # This is also a comment
PrimKey first_name Str [maxlength 70]
Field last_name Str [maxlength 70]
Field instrument Str [default "guitar", maxlength 100]
Field age Int []
Model Album:
PrimKey name Str [maxlength 100]
Field release_date Datetime []
Field num_stars Int []
Relation ManyToOne Album Musician
Model Song:
PrimKey name Str [maxlength 100]
Field lyrics Str [maxlength 1000]
Relation ManyToOne Song Album
Relation ManyToMany Musician songs_written Song musicians