Create the first App Table (vehicle)

One thing to note before we dig into this:

Wutta Framework tends to prefer “singular” as opposed to “plural” table names. For instance widget instead of widgets, and person instead of people.

This is not a strict requirement, however the logic used to generate other names (e.g. routes, permissions) in the web app will often “just work” if the table name is singular. If you have a plural-named table you may need to override more names, but even with singular name you may find you have to override something later anyway.

We’ll go with vehicle for our first table in this tutorial.

New App Table Wizard

The web app comes with a wizard for creating a new table. You typically need to “become root” in order to access it.

This whole idea generally assumes you’ll use it for local development only, with an “editable” install (pip install -e) of your project. The wizard can generate new Python modules directly in your source tree.

Under the Admin menu choose App Info. From there you can click either App Tables or else Alembic Dashboard; either will give you a page which then has a button to start the new table wizard.

The wizard has several steps, and we’ll go over each below. But at a high level it’s just:

  • collect info

  • generate python module for table model

  • generate alembic revision script

  • run alembic to migrate database

At the end you have a fully functional table, backed by Python code which you can modify further as needed.

Enter Details

Hopefully this part is straightforward enough, just have to provide all the naming variations and then define whatever columns are needed.

Note that each table is automatically given a UUID column for primary key, so you only need to define “other” columns.

If you have Continuum versioning enabled then you can choose whether or not that should apply to the table overall, and each column individually.

Note

One last note about naming (!):

It’s probably a good idea to use a custom prefix for your table names. This will help to avoid collisions when many related packages are installed.

It may seem (and be) irrelevant but it’s an easy thing to future-proof.

We’ll use poser_ as table prefix, so here are the values for our vehicle example:

  • Table Name - poser_vehicle

  • Model Class - Vehicle

  • Model Title - Vehicle

  • Model Title Plural - Vehicles

  • Description - Represents a vehicle for which mileage is tracked.

  • Versioning - enabled

And for Columns (all with versioning enabled):

  • name - string, length 50, not nullable

  • make - string, length 50, not nullable

  • model - string, length 50, not nullable

  • year - integer, not nullable

Click the “Details are complete” button when finished.

Write Model

This asks where on disk the wizard should write a new Python module file, containing the table model class.

Even if you intend to add the code to an existing module, you should let the wizard create a new file and then you can cut/paste by hand after this step.

Click the button to write a new file when ready.

Confirm Model

At this point the code for the new table exists, but it is not yet part of the running app. You should first review the new code, do a basic sanity check and ideally define a __str__() method for the model class.

(And here’s where you would cut/paste the code to an existing module, if that’s your intention.)

Once you’re happy with the model class definition, add an import statement for it within the __init__.py module. All relevant file paths and example import statement should be on screen for reference.

Technically the running app may need a restart at this point, to reload all modules. But if you’re running the web app with -r in local dev, you should not need to manually restart.

The ultimate test is whether the running app is “aware” of the new model class; you can click “Check for Model” to confirm that.

Write Migration

Next we let Alembic work its magic; it knows how to compare the Python model definitions with current database schema, and generate a script which would migrate the DB to match the model.

The main thing here is to choose the correct branch. If this is your first table for a new project, you’ll need to create a new branch. The wizard should auto-suggest that for you in this case.

In many cases you won’t need to change anything here, just click the button to generate a new script when ready.

Confirm Migration

As with the model class, you should review the code generated for the migration. Path to the new script is on screen for reference.

It is important to sanity check everything. Although in many cases the code is fine, there can be some edge cases. Thankfully for the “new table wizard” scenario, the risk of edge case is fairly low.

Migrate Database

Moment of truth, this will run the new migration script against the app’s database.

Confirm Table

The new table should now exist in your DB; click “Check for Table” to confirm.

Commit Code

This is just an “outro” page with a reminder to commit all that code you just generated.

From here the last button will take you to view your new “App Table” details, described next.

Viewing the Table

You may already be viewing the table details, but if not you can always find your table via the App Tables area.

This shows various info such as the Python module file in which the table model class is defined, as well as the column details.

In the Cross-Reference panel on the right, you’ll see button link(s) to some “master” view(s) for the table. As well as a button to create a new master view.

What you won’t see here, is the table data. That’s what a master view is for, which we’ll go over in the next section.