Skip to content

Python Inheritance in Datatables


Recap of Key Concepts

Before we proceed, let's quickly review the progress we've made so far...

  • We established our database at ~/simmate/my_env-database.sqlite
  • We ran a quantum-espresso workflow that stored results in our database
  • We introduced Python classes, focusing on the significance of the Structure class

Next, we'll build on these elements and learn about the database.


A Basic Table

Let's start with the basics: what does the table you saw in DBeaver actually look like in Simmate's Python code?

All datatables are represented by a class, and the general format is as follows:

from simmate.database.base_data_types import DatabaseTable, table_column

class MyExampleTable(DatabaseTable):
   column_01 = table_column.CharField()  # CharField --> text storage
   column_02 = table_column.BoolField()  # BoolField --> True/False storage
   column_03 = table_column.FloatField()  # FloatField --> number/decimal storage

The corresponding table (populated with random data) would look like this:

column_01 column_02 column_03
jack True 3.1456
lauren False 299792458
siona True 1.6180
scott False 1.602e-19
... ... ...

Creating tables is as simple as defining a class, declaring it as a DatabaseTable, and specifying the desired columns with table_column.


A Table with Inheritance

However, if we have multiple tables with similar data, this process can become repetitive. For instance, we might want to store structures in various tables, each with columns like density, number of sites, number of elements, etc. To streamline this process, we use Python "inheritance". Here's how it works...

First, we define a table with common data (let's use Person as an example).

from simmate.database.base_data_types import DatabaseTable, table_column

class Person(DatabaseTable):
   name = table_columns.CharField()
   age = table_columns.IntField()
   height = table_columns.FloatField()

Next, we create a separate table that includes this data and more:

class Student(Person):  # <--- note we have Person here instead of DatabaseTable
   year = table_columns.IntField()  # e.g. class of 2020
   gpa = table_columns.FloatField()

The Student datatable now looks like this:

name age height year gpa
jack 15 6.1 2020 3.6
lauren 16 5.8 2019 4.0
siona 15 5.6 2020 3.7
scott 14 6.2 2021 3.2
... ... ... ... ...

Note that the Student table includes both our newly defined columns (year + gpa) as well as all of the columns from Person (name, age, height). This is because Student inherits from Person.


A full example in Simmate

Simmate uses this concept of inheritance with common materials science data. This includes tables for structures, thermodynamic data, site forces, and more.

Let's use the workflows_staticenergy table as an example. Open this table in DBeaver, and take a closer look at all of the columns. This table inherits from several others:

  • Structure
  • Thermodynamics
  • Forces
  • Calculation

This is because the calculation involves the following information, respectively:

  • an input structure (formula, num_sites, density, etc.)
  • thermodynamic data (final energy, energy per atom, stability, etc.)
  • site forces and lattice stress (available because we used DFT to calculate the energy)
  • general calculation info (e.g. calculation time, workflow name, dirctory name, etc.)

This builds out the massive table for us. Then, during analysis, you can go in and select which columns you actually are interested in from the many available.

Tip

Experienced python users: take a look at our source code for the StaticEnergy table here. You'll see we just provide these data types as mix-ins.

Warning

Do not confuse the database table Structure with the toolkit Structure. One represents structural data in a table, while the other helps with advanced analysis and manipulation of a structure. You can use the aliases DatabaseStructure and ToolkitStructure to help keep them separate if you wish.

Note also, you can convert a ToolkitStructure into a single row for a DatabaseStructure. Simmate does this frequently behind the scenes in order to save information to your database.