Adding tables with relationships¶
Updating the models¶
Next we want to prepare actual computations.
For example, if we are interested in storing eigenvalues, we should create a new table for them in my_project.hamiltonian.models.py
...
class Eigenvalue(Base):
"""Model which stores diagonalization information for a given Hamiltonian
"""
hamiltonian = models.ForeignKey(
Contact,
on_delete=models.CASCADE,
help_text="Matrix for which the eigenvalue has been computed.",
)
n_level = models.PositiveIntegerField(
help_text="The nth eigenvalue extracted in ascending order."
)
value = models.FloatField(help_text="The value of the eigenvalue")
class Meta:
unique_together = ["hamiltonian", "n_level"]
Similar to the Contact
model, we have a PositiveIntegerField
which enumerate the eigenvalues and a value
field, now being a FloatField
, as we do not use it for unique constraint comparisons.
The hamiltonian
field, a ForeignKey
field, points to the Contact
table.
On the Python side, this would correspond to
e = Eigenvalue.objects.first()
e.hamiltonian # this is a contact hamiltonian class instance
Also, a backwards access is provided
h = Contact.objects.first()
h.eigenvalue_set.all()
would return of all eigenvalues associated with the hamiltonian.
The on_delete
specifies what happens if a hamiltonian associated with eigenvalues is deleted.
In particularly, the models.CASCADE
means if you delete a hamiltonian you also delete all associated eigenvalues.
Since now the table structure was modified, changes need to be migrated
$ python manage.py makemigrations
Migrations for 'hamiltonian':
my_project/hamiltonian/migrations/0002_eigenvalue.py
- Create model Eigenvalue
and
$ python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, hamiltonian, notifications, sessions
Running migrations:
Applying hamiltonian.0002_eigenvalue... OK
Updating the run script¶
We now want to extend the script to export eigenvalues in case computations are non-existent or incomplete. Non-existent is defined by: “We have no eigenvalues” for a given Hamiltonian, incomplete means: “We find less eigenvalues then expected”.
This logic is implemented by adjusting the main
function in add_data.py
:
...
from my_project.hamiltonian.models import Eigenvalue
def main():
for values in product(*RANGES.values()):
...
compute_entries = True
eigenvalues = Eigenvalue.objects.filter(hamiltonian=hamiltonian)
if eigenvalues.count() == n_sites:
compute_entries = False
else:
print(" Eigenvalues incomplete. Deleting old computation.")
eigenvalues.delete()
if compute_entries:
print(" Computing eigenvalues")
eigs, _ = np.linalg.eigh(hamiltonian.matrix)
print(" Preparing export of eigenvalues")
for n_level, value in enumerate(eigs):
Eigenvalue.objects.create(hamiltonian=hamiltonian, n_level=n_level, value=value)
print("Done")
Running this script will compute all the eigenvalues.
Note
EspressoDB automatically stores `user` and `last_modified` information for each entry. In some cases it might be desirable to also store code revision information. This can be done by specifying the `tag` column. See also [the `pre_save` functionality.](../../features/pre-save.md).