from fastlite import *
from dataclasses import is_dataclassTest Update Operations
Setup
Note: Make sure to use fastlite’s database() here
db = database(':memory:')class People: id: int; name: strpeople = db.create(People, pk='id')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.
count = people.count
assert people.update(None) == {}
assert people.count == countTest empty dict doesn’t change anything
count = people.count
assert people.update({}) == {}
assert people.count == count# Test empty dataclass doesn't change anything
PersonDC = people.dataclass()
count = people.count
assert people.update(PersonDC()) == {}
assert people.count == count# Test empty class instance doesn't change anything
class EmptyPerson: pass
count = people.count
assert people.update(EmptyPerson()) == {}
assert people.count == countSingle Update Types
Test update with dict. Result should include the Updated value
person = people.insert(name='Alice')
adict = dict(id=person.id, name='Bob')
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
dc = People(id=person.id, name='Bobby')
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()
student.name = 'Charlo'
student.id = person.id
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
result = people.update(dict(id=person.id, name=None))
assert result.name is None
assert people[person.id].name == NoneTest with empty string
result = people.update(dict(id=person.id, name=''))
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 fastlite.SqlError, which is a shim for apsw.SqlError:
try:
p = people.update(dict(id=person.id, name='Extra', age=25, title='Dr'))
except SQLError as e:
assert e.args[0] == 'no such column: age'