from fastlite import *
from dataclasses import is_dataclass
Test Update Operations
Setup
Note: Make sure to use fastlite’s database()
here
= database(':memory:') db
class People: id: int; name: str
= db.create(People, pk='id') people
Test Single Updates
Here we test update()
Test Cases for update()
Where Nothing Is Updated
Test that calling insert()
without any parameters doesn’t change anything, and returns nothing
people.update()
{}
Test None doesn’t change anything.
= people.count
count assert people.update(None) == {}
assert people.count == count
Test empty dict doesn’t change anything
= people.count
count assert people.update({}) == {}
assert people.count == count
# Test empty dataclass doesn't change anything
= people.dataclass()
PersonDC = people.count
count assert people.update(PersonDC()) == {}
assert people.count == count
# Test empty class instance doesn't change anything
class EmptyPerson: pass
= people.count
count assert people.update(EmptyPerson()) == {}
assert people.count == count
Single Update Types
Test update with dict
. Result should include the Updated value
= people.insert(name='Alice')
person = dict(id=person.id, name='Bob')
adict assert people.update(adict).name == 'Bob'
assert people[person.id].name == 'Bob'
Fetch record from database to confirm it has changed
assert people[person.id].name == 'Bob'
Test update with dataclass
= People(id=person.id, name='Bobby')
dc assert is_dataclass(dc) is True
assert people.update(dc).name == 'Bobby'
assert people[person.id].name == 'Bobby'
Test with regular class
class Student: pass
= Student()
student = 'Charlo'
student.name id = person.id
student.
assert people.update(student).name == 'Charlo'
assert people[student.id].name == 'Charlo'
None and Empty String Handling
SQLite makes a clear distinction between NULL (represented as None in Python) and an empty string (’’). Unlike some popular Python ORMs, fastlite preserves this distinction because:
- NULL represents “unknown” or “missing” data
- Empty string represents “known to be empty”
These are semantically different concepts, and maintaining this distinction allows users to make appropriate queries (e.g. WHERE name IS NULL
vs WHERE name = ''
). The fact that fastlite preserves this distinction in both directions (Python->SQLite and SQLite->Python) is good database design.
Test updating a record with name set to None
= people.update(dict(id=person.id, name=None))
result assert result.name is None
assert people[person.id].name == None
Test with empty string
= people.update(dict(id=person.id, name=''))
result assert result.name == ''
assert people[person.id].name == ''
Other Cases
Test with special characters
assert people.update(dict(id=person.id, name='O\'Connor')).name == "O'Connor"
assert people[person.id].name == "O'Connor"
assert people.update(dict(id=person.id, name='José')).name == "José"
assert people[person.id].name == "José"
Test that extra fields raise sqlite3.OperationalError
from sqlite3 import OperationalError
try:
= people.update(dict(id=person.id, name='Extra', age=25, title='Dr'))
p except OperationalError as e:
assert e.args[0] == 'no such column: age'