Tags: advanced-user, tutorial

Inserting Records#

This page covers inserting Records into a LinkAhead instance, referencing other records, and updating property values using PyLinkAhead.

Concept

PyLinkAhead

Create a Record

db.Record()

Assign a RecordType to a Record

.add_parent()

Set a property value (with optional unit)

.add_property(name=..., value=..., unit=...)

Retrieve a record from the server

.retrieve()

Update a record

.update()

Fetch a Property by name with server ID

db.get_entity_by_name()

Prerequisites#

Make sure you have completed Creating a Data Model. The examples on this page assume that the relevant RecordTypes and Properties already exist in the database.

Inserting a Record#

db.Record() creates an empty record object in Python. You populate it by assigning a parent RecordType and property values, then call .insert() to write it to the server:

rec = db.Record() # rec.id is None
rec.add_parent(name="Experiment")
rec.add_property(name="date", value="2020-01-07")
rec.insert()
print(rec.id) # rec.id set by the server
Output:#
256

After insertion the server assigns an integer id to the record. The printed value above is an example; the actual id depends on the state of your instance.

Reference Properties#

Records can reference other records. If you already know the id of the target record, use it directly as the property value:

# Create record and assign parent in one line
ana = db.Record().add_parent(name="Analysis")
ana.add_property(name="Experiment", value=rec.id)
ana.add_property(name="date", value="2020-01-08")
# possibly, add more properties here ...
ana.insert()

Alternatively, pass the Python object itself as the value:

ana = db.Record().add_parent(name="Analysis")
ana.add_property(name="Experiment", value=rec)
ana.add_property(name="date", value="2020-01-08")
# possibly, add more properties here ...
ana.insert()

If both records are new, insert them together in a Container. The server resolves the reference during insertion:

rec = db.Record()
rec.add_parent(name="Experiment")
rec.add_property(name="date", value="2020-01-07")
ana = db.Record().add_parent(name="Analysis")
ana.add_property(name="Experiment", value=rec)
ana.add_property(name="date", value="2020-01-08")

# Add experiment and analysis records to our container
cont = db.Container()
cont.extend([rec, ana])
# Insert both at the same time, the LinkAhead server
# will resolve the reference upon insertion.
cont.insert()

All three approaches produce an Analysis record that references an Experiment record.

Named Records and Units#

Records can have a name and properties can carry units:

rec = db.Record("DeviceNo-AB110")
rec.add_parent(name="SlicingMachine")
rec.add_property(name="weight", value="1749", unit="kg")
rec.insert()
print(rec.name)
print(rec.id)
Output:#
DeviceNo-AB110
301

The name is preserved after insertion and the server assigns an id.

Batch Insertion#

To insert many records at once, build a Container in a loop and call .insert() once at the end:

cont = db.Container()
for date, result in analysis_results:
   rec = db.Record()
   rec.add_parent(name="Experiment")
   rec.add_property(name="date", value=date)
   rec.add_property(name="result", value=result)
   cont.append(rec)

cont.insert()
print(len(cont))
Output:#
3

Working with List Values#

Use .retrieve() to fetch the current state of a record from the server by name or id. The following example inserts a record with an initial list value, retrieves it, extends the list, and persists the change with .update():

db.Record(name="TestRec").add_parent("TestType").add_property(
    name="TestList", value=[1,2,3]).insert()
retrieved = db.Record(name="TestRec").retrieve()
retrieved.get_property("TestList").value += [4,5]
retrieved.update()

# confirm the updated value
retrieved = db.Record(name="TestRec").retrieve()
print(retrieved.get_property("TestList").value)
Output:#
[1, 2, 3, 4, 5]

.retrieve() is necessary before modifying because .update() sends the entire local object state back to the server. Modifying a record without retrieving first would overwrite the server’s current value rather than extending it.

Updating Records#

When you update a record, any property you add must already have an id. Adding a property by name alone will fail:

experiment = db.Record(name="IncompleteRecord").retrieve()
experiment.add_property(name='date', value="2020-01-01")
experiment.update()  # Fails! The 'date' Property needs to have an ID.
Output:#
TransactionError: PROPERTY (id: None, name: 'date') CAUSED EntityError: Entity has no ID.

Use get_entity_by_name() to fetch the Property entity with its id before adding it:

experiment = db.Record(name="IncompleteRecord").retrieve()
experiment.add_property(db.get_entity_by_name('date'), value="2020-01-01")
experiment.update()  # Works!

Additional information about record retrieval and caching for performance-sensitive code can be found in the Features of Interest document.

For updating uploaded files, see How to Update a File.

Summary#

This tutorial covered inserting Records, using reference properties, batch insertion, working with list values, and updating records correctly.

Continue with Scripting with LinkAhead for a demonstration on how to build a script to automatically update data in linkahead.