Schema
Define your data models with Isar collections
Schema
When you use Isar to store your app's data, you're dealing with collections. A collection is like a database table and can only contain a single type of Dart object.
Anatomy of a Collection
You define each Isar collection by annotating a class with @collection or @Collection().
@collection
class User {
Id? id;
String? firstName;
String? lastName;
}To persist a field, Isar must have access to it. Make it public or provide getter and setter methods.
Data Types
Isar supports the following data types:
Primitive Types
@collection
class PrimitiveTypes {
PrimitiveTypes(this.id);
final int id;
bool? boolValue;
int? intValue;
double? doubleValue;
DateTime? dateValue;
String? stringValue;
}Lists
@collection
class ListTypes {
ListTypes(this.id);
final int id;
List<bool>? boolList;
List<int>? intList;
List<double>? doubleList;
List<DateTime>? dateList;
List<String>? stringList;
}Lists cannot contain null values. Use nullable types instead.
Enums
enum Status { active, inactive, pending }
@collection
class Task {
Task(this.id);
final int id;
@enumerated
Status? status;
@Enumerated(EnumType.ordinal)
Status? ordinalStatus;
@Enumerated(EnumType.name)
Status? namedStatus;
}Stores the index of the enum value (default).
// Status.active = 0
// Status.inactive = 1
// Status.pending = 2Stores the name of the enum value as String.
// Status.active = 'active'
// Status.inactive = 'inactive'Stores a custom value defined in the enum.
enum Status {
@EnumValue(1) active,
@EnumValue(2) inactive,
@EnumValue(3) pending,
}Embedded Objects
@embedded
class Address {
String? street;
String? city;
String? country;
}
@collection
class Person {
Person(this.id);
final int id;
String? name;
Address? address;
List<Address>? addresses;
}Ids
Every collection needs an Id field to uniquely identify objects.
@collection
class User {
User(this.id);
final int id;
String? name;
}For auto-incrementing IDs, use the collection.autoIncrement() method when inserting:
isar.write((isar) {
final user = User(isar.users.autoIncrement());
isar.users.put(user);
});Custom IDs
@collection
class User {
User(this.id);
final int id; // You manage the ID
String? name;
}Field Annotations
@Index
Create indexes for better query performance:
@collection
class User {
User(this.id);
final int id;
@Index()
String? email;
@Index(type: IndexType.value)
String? username;
@Index(caseSensitive: false)
String? name;
}@Ignore
Exclude fields from storage:
@collection
class User {
User(this.id);
final int id;
String? name;
@ignore
String? temporaryData; // Not stored
}@Name
Rename fields in the database:
@collection
class User {
User(this.id);
final int id;
@Name("user_name")
String? name;
}@Size
Limit string size:
@collection
class User {
User(this.id);
final int id;
@Size(max: 100)
String? shortText;
@Size(max: 1000)
String? longText;
}Composite Indexes
Create indexes on multiple fields:
@collection
@Index(composite: ['lastName', 'age'])
class User {
User(this.id);
final int id;
String? firstName;
String? lastName;
int? age;
}Modeling Relationships
Isar Plus v4 models relationships with embedded objects or manual ID fields instead of runtime link types. See the dedicated Relationships page for concrete examples lifted from the codebase.
Migration
Isar handles schema migrations automatically in most cases:
- Adding new fields
- Removing fields
- Changing field types (with data loss)
- Adding/removing indexes
Changing the type of an existing field will result in data loss for that field.
Next Steps
Last Update