How to delete records?¶
SQLRecords can be deleted with record.delete(), which will permanently remove them from your database.
When it comes to records of Artifact and Collection, they are “moved into trash” when you first call record.delete().
Trashed records are invisible in the UI and excluded from the query results.
If a record is already in the trash or
permanent=Trueis passed, callingrecord.delete()triggers permanent delete.
# !pip install lamindb
!lamin init --storage test-delete
→ initialized lamindb: testuser1/test-delete
import lamindb as ln
import pandas as pd
→ connected lamindb: testuser1/test-delete
artifact = ln.Artifact.from_dataframe(
pd.DataFrame({"a": [1, 2], "b": [3, 4]}), description="mydf"
)
artifact.save()
! no run & transform got linked, call `ln.track()` & re-run
Artifact(uid='J2UsuEx7KD71Z7oq0000', is_latest=True, description='mydf', suffix='.parquet', kind='dataset', otype='DataFrame', size=2068, hash='eM_il92GbTmhwqdnSMYd2w', n_observations=2, branch_id=1, space_id=1, storage_id=1, created_by_id=1, created_at=2025-10-16 11:49:50 UTC, is_locked=False)
ln.Artifact.to_dataframe()
| uid | key | description | suffix | kind | otype | size | hash | n_files | n_observations | _hash_type | _key_is_virtual | _overwrite_versions | space_id | storage_id | schema_id | version | is_latest | is_locked | run_id | created_at | created_by_id | _aux | _real_key | branch_id | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| id | |||||||||||||||||||||||||
| 1 | J2UsuEx7KD71Z7oq0000 | None | mydf | .parquet | dataset | DataFrame | 2068 | eM_il92GbTmhwqdnSMYd2w | None | 2 | md5 | True | False | 1 | 1 | None | None | True | False | None | 2025-10-16 11:49:50.386000+00:00 | 1 | {'af': {'0': True}} | None | 1 |
Trash an artifact¶
artifact.delete()
! moved record to trash (branch_id = -1): Artifact(uid='J2UsuEx7KD71Z7oq0000', is_latest=True, description='mydf', suffix='.parquet', kind='dataset', otype='DataFrame', size=2068, hash='eM_il92GbTmhwqdnSMYd2w', n_observations=2, branch_id=-1, space_id=1, storage_id=1, created_by_id=1, created_at=2025-10-16 11:49:50 UTC, is_locked=False)
No longer visible:
ln.Artifact.to_dataframe()
| uid | id | key | description | suffix | kind | otype | size | hash | n_files | n_observations | _hash_type | _key_is_virtual | _overwrite_versions | space_id | storage_id | schema_id | version | is_latest | is_locked | run_id | created_at | created_by_id | _aux | _real_key | branch_id |
|---|
But the artifact still exists in the database and in storage, you can find it by passing None to the visibility filter:
ln.Artifact.filter(visibility=None).to_dataframe()
| uid | key | description | suffix | kind | otype | size | hash | n_files | n_observations | _hash_type | _key_is_virtual | _overwrite_versions | space_id | storage_id | schema_id | version | is_latest | is_locked | run_id | created_at | created_by_id | _aux | _real_key | branch_id | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| id | |||||||||||||||||||||||||
| 1 | J2UsuEx7KD71Z7oq0000 | None | mydf | .parquet | dataset | DataFrame | 2068 | eM_il92GbTmhwqdnSMYd2w | None | 2 | md5 | True | False | 1 | 1 | None | None | True | False | None | 2025-10-16 11:49:50.386000+00:00 | 1 | {'af': {'0': True}} | None | -1 |
You can restore an artifact from trash:
artifact.restore()
ln.Artifact.to_dataframe()
| uid | key | description | suffix | kind | otype | size | hash | n_files | n_observations | _hash_type | _key_is_virtual | _overwrite_versions | space_id | storage_id | schema_id | version | is_latest | is_locked | run_id | created_at | created_by_id | _aux | _real_key | branch_id | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| id | |||||||||||||||||||||||||
| 1 | J2UsuEx7KD71Z7oq0000 | None | mydf | .parquet | dataset | DataFrame | 2068 | eM_il92GbTmhwqdnSMYd2w | None | 2 | md5 | True | False | 1 | 1 | None | None | True | False | None | 2025-10-16 11:49:50.386000+00:00 | 1 | {'af': {'0': True}} | None | 1 |
ln.Storage.to_dataframe()
| uid | root | description | type | region | instance_uid | space_id | is_locked | run_id | created_at | created_by_id | _aux | branch_id | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| id | |||||||||||||
| 1 | zeOhU51mdlv9 | /home/runner/work/lamindb/lamindb/docs/faq/tes... | None | local | None | 4Kf3utIIfnlJ | 1 | False | None | 2025-10-16 11:49:48.072000+00:00 | 1 | None | 1 |
Permanent delete¶
Calling artifact.delete on a trashed artifact triggers a permanent delete dialog. You can pass permanent=True to auto-confirm the deletion.
artifact.delete(permanent=True)
Now its gone in the database:
ln.Artifact.filter(visibility=None).to_dataframe()
| uid | id | key | description | suffix | kind | otype | size | hash | n_files | n_observations | _hash_type | _key_is_virtual | _overwrite_versions | space_id | storage_id | schema_id | version | is_latest | is_locked | run_id | created_at | created_by_id | _aux | _real_key | branch_id |
|---|
!lamin delete --force test-delete
• deleting instance testuser1/test-delete