Each piece of data or information in Appwrite Databases is a row. Rows have a structure defined by the parent table.
Create rows
Permissions required
You must grant create permissions to users at the table level before users can create rows. Learn more about permissions
In most use cases, you will create rows programmatically.
During testing, you might prefer to create rows in the Appwrite Console. To do so, navigate to the Rows tab of your table and click the Add row button.
List rows
Permissions required
You must grant read permissions to users at the table level before users can read rows. Learn more about permissions
Rows can be retrieved using the List Row endpoint.
Results can be filtered, sorted, and paginated using Appwrite's shared set of query methods. You can find a full guide on querying in the Queries Guide.
By default, results are limited to the first 25 items. You can change this through pagination.
Update row
Permissions required
You must grant update permissions to users at the table level or row level before users can update rows. Learn more about permissions
In most use cases, you will update rows programmatically.
Upsert rows
Upsert is a combination of "update" and "insert" operations. It creates a new row if one doesn't exist with the given ID, or updates an existing row if it does exist.
In most use cases, you will upsert rows programmatically.
Permissions required
You must grant create permissions to users at the table level, and update permissions to users at the table or row level before users can upsert rows. Learn more about permissions
Type safety with models
Mobile and native SDKs provide type safety when working with rows through the nestedType
parameter. This allows you to specify custom model types for complete auto-completion and type safety.
Define your model
Create a data class or struct that matches your table structure:
data class Book(
val title: String,
val author: String,
val publishedYear: Int? = null,
val genre: List<String>? = null,
val isAvailable: Boolean = true
)
struct Book: Codable {
let title: String
let author: String
let publishedYear: Int?
let genre: [String]?
let isAvailable: Bool
}
interface Book {
title: string;
author: string;
publishedYear?: number;
genre?: string[];
isAvailable: boolean;
}
Using type-safe operations
Use the nestedType
parameter for full type safety in native SDKs, or generics in web SDKs:
Model methods
Models returned by native SDKs include helpful utility methods:
val book = books.rows.first()
// Convert model to Map for debugging or manual manipulation
val bookMap = book.toMap()
Log.d("Appwrite", "Book data: ${bookMap}")
// Create model instance from Map data
val bookData = mapOf(
"title" to "1984",
"author" to "George Orwell",
"isAvailable" to false
)
val newBook = Book.from(bookData, Book::class.java)
// JSON serialization using Gson (used internally by SDK)
import com.google.gson.Gson
val gson = Gson()
val jsonString = gson.toJson(book)
val bookFromJson = gson.fromJson(jsonString, Book::class.java)
let book = books.rows.first!
// Convert model to dictionary for debugging
let bookMap = book.toMap()
print("Book data: \(bookMap)")
// Create model instance from dictionary
let bookData: [String: Any] = [
"title": "1984",
"author": "George Orwell",
"isAvailable": false
]
let newBook = Book.from(map: bookData)
// JSON encoding using Swift's Codable
let jsonData = try JSONEncoder().encode(book)
let jsonString = String(data: jsonData, encoding: .utf8)
// JSON decoding
if let jsonString = jsonString,
let data = jsonString.data(using: .utf8) {
let bookFromJson = try JSONDecoder().decode(Book.self, from: data)
}
Generate types automatically
You can automatically generate model definitions for your tables using the Appwrite CLI. Run appwrite types collection
to generate types based on your database schema.
Permissions
In Appwrite, permissions can be granted at the table level and the row level. Before a user can create a row, you need to grant create permissions to the user.
Read, update, and delete permissions can be granted at both the table and row level. Users only need to be granted access at either the table or row level to access rows.