From 2a3923bb2512b43940e65ad741d4ebadd245c4dd Mon Sep 17 00:00:00 2001 From: Atharva Deosthale Date: Fri, 26 Jun 2026 17:20:23 +0530 Subject: [PATCH 1/8] Restructure databases docs into per-database-type sections Split the Databases docs into a menu of database types. The /docs/products/databases overview becomes a menu (Appwrite databases: TablesDB, DocumentsDB, VectorsDB; Native databases: PostgreSQL, MySQL). Existing TablesDB content moves under /tablesdb with its full sidebar; DocumentsDB, VectorsDB, PostgreSQL, and MySQL get their own sections with placeholder overviews. Adds redirects for all moved pages. --- src/redirects.json | 142 +++++++++++++++++- .../databases/(overview)/+layout.svelte | 64 ++++++++ .../databases/(overview)/+page.markdoc | 40 +++++ .../databases/documentsdb/+layout.svelte | 29 ++++ .../databases/documentsdb/+page.markdoc | 11 ++ .../products/databases/mysql/+layout.svelte | 29 ++++ .../products/databases/mysql/+page.markdoc | 11 ++ .../databases/postgresql/+layout.svelte | 29 ++++ .../databases/postgresql/+page.markdoc | 11 ++ .../databases/{ => tablesdb}/+layout.svelte | 54 +++---- .../databases/{ => tablesdb}/+page.markdoc | 6 +- .../ai-suggestions/+page.markdoc | 0 .../atomic-numeric-operations/+page.markdoc | 0 .../{ => tablesdb}/backups/+page.markdoc | 0 .../bulk-operations/+page.markdoc | 0 .../{ => tablesdb}/csv-exports/+page.markdoc | 0 .../{ => tablesdb}/csv-imports/+page.markdoc | 0 .../{ => tablesdb}/databases/+page.markdoc | 0 .../{ => tablesdb}/geo-queries/+page.markdoc | 0 .../{ => tablesdb}/legacy/+layout.svelte | 0 .../databases/{ => tablesdb}/legacy/+page.ts | 0 .../atomic-numeric-operations/+page.markdoc | 0 .../legacy/bulk-operations/+page.markdoc | 0 .../legacy/collections/+page.markdoc | 0 .../legacy/databases/+page.markdoc | 0 .../legacy/documents/+page.markdoc | 0 .../{ => tablesdb}/legacy/order/+page.markdoc | 0 .../legacy/pagination/+page.markdoc | 0 .../legacy/permissions/+page.markdoc | 0 .../legacy/queries/+page.markdoc | 0 .../legacy/quick-start/+page.markdoc | 0 .../legacy/relationships/+page.markdoc | 0 .../legacy/type-generation/+page.markdoc | 0 .../{ => tablesdb}/offline/+page.markdoc | 0 .../{ => tablesdb}/operators/+page.markdoc | 0 .../{ => tablesdb}/order/+page.markdoc | 0 .../{ => tablesdb}/pagination/+page.markdoc | 0 .../{ => tablesdb}/permissions/+page.markdoc | 0 .../{ => tablesdb}/queries/+page.markdoc | 0 .../{ => tablesdb}/quick-start/+page.markdoc | 0 .../relationships/+page.markdoc | 0 .../{ => tablesdb}/rows/+page.markdoc | 0 .../{ => tablesdb}/tables/+page.markdoc | 0 .../timestamp-overrides/+page.markdoc | 0 .../{ => tablesdb}/transactions/+page.markdoc | 0 .../type-generation/+page.markdoc | 0 .../databases/vectorsdb/+layout.svelte | 29 ++++ .../databases/vectorsdb/+page.markdoc | 11 ++ 48 files changed, 431 insertions(+), 35 deletions(-) create mode 100644 src/routes/docs/products/databases/(overview)/+layout.svelte create mode 100644 src/routes/docs/products/databases/(overview)/+page.markdoc create mode 100644 src/routes/docs/products/databases/documentsdb/+layout.svelte create mode 100644 src/routes/docs/products/databases/documentsdb/+page.markdoc create mode 100644 src/routes/docs/products/databases/mysql/+layout.svelte create mode 100644 src/routes/docs/products/databases/mysql/+page.markdoc create mode 100644 src/routes/docs/products/databases/postgresql/+layout.svelte create mode 100644 src/routes/docs/products/databases/postgresql/+page.markdoc rename src/routes/docs/products/databases/{ => tablesdb}/+layout.svelte (70%) rename src/routes/docs/products/databases/{ => tablesdb}/+page.markdoc (70%) rename src/routes/docs/products/databases/{ => tablesdb}/ai-suggestions/+page.markdoc (100%) rename src/routes/docs/products/databases/{ => tablesdb}/atomic-numeric-operations/+page.markdoc (100%) rename src/routes/docs/products/databases/{ => tablesdb}/backups/+page.markdoc (100%) rename src/routes/docs/products/databases/{ => tablesdb}/bulk-operations/+page.markdoc (100%) rename src/routes/docs/products/databases/{ => tablesdb}/csv-exports/+page.markdoc (100%) rename src/routes/docs/products/databases/{ => tablesdb}/csv-imports/+page.markdoc (100%) rename src/routes/docs/products/databases/{ => tablesdb}/databases/+page.markdoc (100%) rename src/routes/docs/products/databases/{ => tablesdb}/geo-queries/+page.markdoc (100%) rename src/routes/docs/products/databases/{ => tablesdb}/legacy/+layout.svelte (100%) rename src/routes/docs/products/databases/{ => tablesdb}/legacy/+page.ts (100%) rename src/routes/docs/products/databases/{ => tablesdb}/legacy/atomic-numeric-operations/+page.markdoc (100%) rename src/routes/docs/products/databases/{ => tablesdb}/legacy/bulk-operations/+page.markdoc (100%) rename src/routes/docs/products/databases/{ => tablesdb}/legacy/collections/+page.markdoc (100%) rename src/routes/docs/products/databases/{ => tablesdb}/legacy/databases/+page.markdoc (100%) rename src/routes/docs/products/databases/{ => tablesdb}/legacy/documents/+page.markdoc (100%) rename src/routes/docs/products/databases/{ => tablesdb}/legacy/order/+page.markdoc (100%) rename src/routes/docs/products/databases/{ => tablesdb}/legacy/pagination/+page.markdoc (100%) rename src/routes/docs/products/databases/{ => tablesdb}/legacy/permissions/+page.markdoc (100%) rename src/routes/docs/products/databases/{ => tablesdb}/legacy/queries/+page.markdoc (100%) rename src/routes/docs/products/databases/{ => tablesdb}/legacy/quick-start/+page.markdoc (100%) rename src/routes/docs/products/databases/{ => tablesdb}/legacy/relationships/+page.markdoc (100%) rename src/routes/docs/products/databases/{ => tablesdb}/legacy/type-generation/+page.markdoc (100%) rename src/routes/docs/products/databases/{ => tablesdb}/offline/+page.markdoc (100%) rename src/routes/docs/products/databases/{ => tablesdb}/operators/+page.markdoc (100%) rename src/routes/docs/products/databases/{ => tablesdb}/order/+page.markdoc (100%) rename src/routes/docs/products/databases/{ => tablesdb}/pagination/+page.markdoc (100%) rename src/routes/docs/products/databases/{ => tablesdb}/permissions/+page.markdoc (100%) rename src/routes/docs/products/databases/{ => tablesdb}/queries/+page.markdoc (100%) rename src/routes/docs/products/databases/{ => tablesdb}/quick-start/+page.markdoc (100%) rename src/routes/docs/products/databases/{ => tablesdb}/relationships/+page.markdoc (100%) rename src/routes/docs/products/databases/{ => tablesdb}/rows/+page.markdoc (100%) rename src/routes/docs/products/databases/{ => tablesdb}/tables/+page.markdoc (100%) rename src/routes/docs/products/databases/{ => tablesdb}/timestamp-overrides/+page.markdoc (100%) rename src/routes/docs/products/databases/{ => tablesdb}/transactions/+page.markdoc (100%) rename src/routes/docs/products/databases/{ => tablesdb}/type-generation/+page.markdoc (100%) create mode 100644 src/routes/docs/products/databases/vectorsdb/+layout.svelte create mode 100644 src/routes/docs/products/databases/vectorsdb/+page.markdoc diff --git a/src/redirects.json b/src/redirects.json index 17340a23b84..65ebd11afc0 100644 --- a/src/redirects.json +++ b/src/redirects.json @@ -97,15 +97,15 @@ }, { "link": "/docs/databases-queries", - "redirect": "/docs/products/databases/queries" + "redirect": "/docs/products/databases/tablesdb/queries" }, { "link": "/docs/databases-pagination", - "redirect": "/docs/products/databases/pagination" + "redirect": "/docs/products/databases/tablesdb/pagination" }, { "link": "/docs/databases-relationships", - "redirect": "/docs/products/databases/relationships" + "redirect": "/docs/products/databases/tablesdb/relationships" }, { "link": "/docs/storage", @@ -213,11 +213,11 @@ }, { "link": "/docs/queries", - "redirect": "/docs/products/databases/queries" + "redirect": "/docs/products/databases/tablesdb/queries" }, { "link": "/docs/pagination", - "redirect": "/docs/products/databases/pagination" + "redirect": "/docs/products/databases/tablesdb/pagination" }, { "link": "/docs/webhooks", @@ -915,5 +915,137 @@ { "link": "/heroes", "redirect": "/" + }, + { + "link": "/docs/products/databases/ai-suggestions", + "redirect": "/docs/products/databases/tablesdb/ai-suggestions" + }, + { + "link": "/docs/products/databases/atomic-numeric-operations", + "redirect": "/docs/products/databases/tablesdb/atomic-numeric-operations" + }, + { + "link": "/docs/products/databases/backups", + "redirect": "/docs/products/databases/tablesdb/backups" + }, + { + "link": "/docs/products/databases/bulk-operations", + "redirect": "/docs/products/databases/tablesdb/bulk-operations" + }, + { + "link": "/docs/products/databases/csv-exports", + "redirect": "/docs/products/databases/tablesdb/csv-exports" + }, + { + "link": "/docs/products/databases/csv-imports", + "redirect": "/docs/products/databases/tablesdb/csv-imports" + }, + { + "link": "/docs/products/databases/databases", + "redirect": "/docs/products/databases/tablesdb/databases" + }, + { + "link": "/docs/products/databases/geo-queries", + "redirect": "/docs/products/databases/tablesdb/geo-queries" + }, + { + "link": "/docs/products/databases/legacy/atomic-numeric-operations", + "redirect": "/docs/products/databases/tablesdb/legacy/atomic-numeric-operations" + }, + { + "link": "/docs/products/databases/legacy/bulk-operations", + "redirect": "/docs/products/databases/tablesdb/legacy/bulk-operations" + }, + { + "link": "/docs/products/databases/legacy/collections", + "redirect": "/docs/products/databases/tablesdb/legacy/collections" + }, + { + "link": "/docs/products/databases/legacy/databases", + "redirect": "/docs/products/databases/tablesdb/legacy/databases" + }, + { + "link": "/docs/products/databases/legacy/documents", + "redirect": "/docs/products/databases/tablesdb/legacy/documents" + }, + { + "link": "/docs/products/databases/legacy/order", + "redirect": "/docs/products/databases/tablesdb/legacy/order" + }, + { + "link": "/docs/products/databases/legacy/pagination", + "redirect": "/docs/products/databases/tablesdb/legacy/pagination" + }, + { + "link": "/docs/products/databases/legacy/permissions", + "redirect": "/docs/products/databases/tablesdb/legacy/permissions" + }, + { + "link": "/docs/products/databases/legacy/queries", + "redirect": "/docs/products/databases/tablesdb/legacy/queries" + }, + { + "link": "/docs/products/databases/legacy/quick-start", + "redirect": "/docs/products/databases/tablesdb/legacy/quick-start" + }, + { + "link": "/docs/products/databases/legacy/relationships", + "redirect": "/docs/products/databases/tablesdb/legacy/relationships" + }, + { + "link": "/docs/products/databases/legacy/type-generation", + "redirect": "/docs/products/databases/tablesdb/legacy/type-generation" + }, + { + "link": "/docs/products/databases/offline", + "redirect": "/docs/products/databases/tablesdb/offline" + }, + { + "link": "/docs/products/databases/operators", + "redirect": "/docs/products/databases/tablesdb/operators" + }, + { + "link": "/docs/products/databases/order", + "redirect": "/docs/products/databases/tablesdb/order" + }, + { + "link": "/docs/products/databases/pagination", + "redirect": "/docs/products/databases/tablesdb/pagination" + }, + { + "link": "/docs/products/databases/permissions", + "redirect": "/docs/products/databases/tablesdb/permissions" + }, + { + "link": "/docs/products/databases/queries", + "redirect": "/docs/products/databases/tablesdb/queries" + }, + { + "link": "/docs/products/databases/quick-start", + "redirect": "/docs/products/databases/tablesdb/quick-start" + }, + { + "link": "/docs/products/databases/relationships", + "redirect": "/docs/products/databases/tablesdb/relationships" + }, + { + "link": "/docs/products/databases/rows", + "redirect": "/docs/products/databases/tablesdb/rows" + }, + { + "link": "/docs/products/databases/tables", + "redirect": "/docs/products/databases/tablesdb/tables" + }, + { + "link": "/docs/products/databases/timestamp-overrides", + "redirect": "/docs/products/databases/tablesdb/timestamp-overrides" + }, + { + "link": "/docs/products/databases/transactions", + "redirect": "/docs/products/databases/tablesdb/transactions" + }, + { + "link": "/docs/products/databases/type-generation", + "redirect": "/docs/products/databases/tablesdb/type-generation" } ] diff --git a/src/routes/docs/products/databases/(overview)/+layout.svelte b/src/routes/docs/products/databases/(overview)/+layout.svelte new file mode 100644 index 00000000000..ae270c5d9e4 --- /dev/null +++ b/src/routes/docs/products/databases/(overview)/+layout.svelte @@ -0,0 +1,64 @@ + + + + + + {@render children()} + diff --git a/src/routes/docs/products/databases/(overview)/+page.markdoc b/src/routes/docs/products/databases/(overview)/+page.markdoc new file mode 100644 index 00000000000..635ec2fd952 --- /dev/null +++ b/src/routes/docs/products/databases/(overview)/+page.markdoc @@ -0,0 +1,40 @@ +--- +layout: article +title: Databases +description: Store and query your application data with Appwrite Databases. Choose between Appwrite databases with managed APIs and dedicated native databases with direct access. +--- + +Appwrite Databases provide performant and scalable storage for your application, business, and user data. Choose the database that fits your use case, from managed APIs with permissions and realtime to dedicated native engines you connect to directly. + +{% info title="Looking for file storage?" %} +Databases store data. If you need to store files like images, PDFs, or videos, use [Appwrite Storage](/docs/products/storage). +{% /info %} + +# Appwrite databases {% #appwrite-databases %} + +Managed databases with an Appwrite API on top, including permissions, indexes, queries, and realtime. Available on shared and dedicated infrastructure. + +{% cards %} +{% cards_item href="/docs/products/databases/tablesdb" title="TablesDB" %} +Structured, relational data with typed columns, rows, relationships, and indexes. +{% /cards_item %} +{% cards_item href="/docs/products/databases/documentsdb" title="DocumentsDB" %} +Schemaless document storage for flexible, JSON-style data. +{% /cards_item %} +{% cards_item href="/docs/products/databases/vectorsdb" title="VectorsDB" %} +Store embeddings and run similarity search to power AI features. +{% /cards_item %} +{% /cards %} + +# Native databases {% #native-databases %} + +Native database engines provisioned for your project with direct connection access and no abstraction layer. Available on dedicated infrastructure. + +{% cards %} +{% cards_item href="/docs/products/databases/postgresql" title="PostgreSQL" %} +A dedicated, native PostgreSQL database you connect to directly. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql" title="MySQL" %} +A dedicated, native MySQL database you connect to directly. +{% /cards_item %} +{% /cards %} diff --git a/src/routes/docs/products/databases/documentsdb/+layout.svelte b/src/routes/docs/products/databases/documentsdb/+layout.svelte new file mode 100644 index 00000000000..3d2666cc56d --- /dev/null +++ b/src/routes/docs/products/databases/documentsdb/+layout.svelte @@ -0,0 +1,29 @@ + + + + + + {@render children()} + diff --git a/src/routes/docs/products/databases/documentsdb/+page.markdoc b/src/routes/docs/products/databases/documentsdb/+page.markdoc new file mode 100644 index 00000000000..9c70cfae243 --- /dev/null +++ b/src/routes/docs/products/databases/documentsdb/+page.markdoc @@ -0,0 +1,11 @@ +--- +layout: article +title: DocumentsDB +description: Store schemaless documents in collections with Appwrite DocumentsDB for flexible, JSON-style application data. +--- + +Appwrite DocumentsDB stores schemaless documents in collections, giving you flexible, JSON-style data without a fixed schema. It shares the same permissions, indexes, queries, transactions, and realtime concepts as the rest of Appwrite Databases. + +{% info title="Documentation in progress" %} +Detailed DocumentsDB guides are on the way. For now, the concepts in [TablesDB](/docs/products/databases/tablesdb) are the closest reference. +{% /info %} diff --git a/src/routes/docs/products/databases/mysql/+layout.svelte b/src/routes/docs/products/databases/mysql/+layout.svelte new file mode 100644 index 00000000000..f6fe631eea8 --- /dev/null +++ b/src/routes/docs/products/databases/mysql/+layout.svelte @@ -0,0 +1,29 @@ + + + + + + {@render children()} + diff --git a/src/routes/docs/products/databases/mysql/+page.markdoc b/src/routes/docs/products/databases/mysql/+page.markdoc new file mode 100644 index 00000000000..de42e29c3bd --- /dev/null +++ b/src/routes/docs/products/databases/mysql/+page.markdoc @@ -0,0 +1,11 @@ +--- +layout: article +title: MySQL +description: Run a dedicated, native MySQL database provisioned for your project and connect to it directly with standard MySQL clients. +--- + +Run a dedicated, native MySQL database provisioned for your project. Connect to it directly with standard MySQL clients and tools, with no Appwrite abstraction layer in between. Native databases are available on dedicated infrastructure. + +{% info title="Documentation in progress" %} +Detailed MySQL setup and connection guides are on the way. +{% /info %} diff --git a/src/routes/docs/products/databases/postgresql/+layout.svelte b/src/routes/docs/products/databases/postgresql/+layout.svelte new file mode 100644 index 00000000000..de7adff91d5 --- /dev/null +++ b/src/routes/docs/products/databases/postgresql/+layout.svelte @@ -0,0 +1,29 @@ + + + + + + {@render children()} + diff --git a/src/routes/docs/products/databases/postgresql/+page.markdoc b/src/routes/docs/products/databases/postgresql/+page.markdoc new file mode 100644 index 00000000000..4e7c251d8da --- /dev/null +++ b/src/routes/docs/products/databases/postgresql/+page.markdoc @@ -0,0 +1,11 @@ +--- +layout: article +title: PostgreSQL +description: Run a dedicated, native PostgreSQL database provisioned for your project and connect to it directly with standard PostgreSQL clients. +--- + +Run a dedicated, native PostgreSQL database provisioned for your project. Connect to it directly with standard PostgreSQL clients and tools, with no Appwrite abstraction layer in between. Native databases are available on dedicated infrastructure. + +{% info title="Documentation in progress" %} +Detailed PostgreSQL setup and connection guides are on the way. +{% /info %} diff --git a/src/routes/docs/products/databases/+layout.svelte b/src/routes/docs/products/databases/tablesdb/+layout.svelte similarity index 70% rename from src/routes/docs/products/databases/+layout.svelte rename to src/routes/docs/products/databases/tablesdb/+layout.svelte index 87f1ffb5a32..ca05c54b16a 100644 --- a/src/routes/docs/products/databases/+layout.svelte +++ b/src/routes/docs/products/databases/tablesdb/+layout.svelte @@ -10,7 +10,7 @@ let { children } = $props(); const parent: NavParent = { - href: '/docs', + href: '/docs/products/databases', label: 'Databases' }; @@ -20,11 +20,11 @@ items: [ { label: 'Overview', - href: '/docs/products/databases' + href: '/docs/products/databases/tablesdb' }, { label: 'Quick start', - href: '/docs/products/databases/quick-start' + href: '/docs/products/databases/tablesdb/quick-start' } ] }, @@ -33,45 +33,45 @@ items: [ { label: 'Databases', - href: '/docs/products/databases/databases' + href: '/docs/products/databases/tablesdb/databases' }, { label: 'Tables', - href: '/docs/products/databases/tables' + href: '/docs/products/databases/tablesdb/tables' }, { label: 'Rows', - href: '/docs/products/databases/rows' + href: '/docs/products/databases/tablesdb/rows' }, { label: 'Permissions', - href: '/docs/products/databases/permissions' + href: '/docs/products/databases/tablesdb/permissions' }, { label: 'Relationships', - href: '/docs/products/databases/relationships' + href: '/docs/products/databases/tablesdb/relationships' }, { label: 'Queries', - href: '/docs/products/databases/queries' + href: '/docs/products/databases/tablesdb/queries' }, { label: 'Order', - href: '/docs/products/databases/order' + href: '/docs/products/databases/tablesdb/order' }, { label: 'Operators', - href: '/docs/products/databases/operators', + href: '/docs/products/databases/tablesdb/operators', new: isNewUntil('31 Dec 2025') }, { label: 'Geo queries', - href: '/docs/products/databases/geo-queries', + href: '/docs/products/databases/tablesdb/geo-queries', new: isNewUntil('30 Sep 2025') }, { label: 'Backups', - href: '/docs/products/databases/backups' + href: '/docs/products/databases/tablesdb/backups' } ] }, @@ -80,50 +80,50 @@ items: [ { label: 'Pagination', - href: '/docs/products/databases/pagination' + href: '/docs/products/databases/tablesdb/pagination' }, { label: 'Transactions', - href: '/docs/products/databases/transactions', + href: '/docs/products/databases/tablesdb/transactions', new: isNewUntil('31 Oct 2025') }, { label: 'Type generation', - href: '/docs/products/databases/type-generation', + href: '/docs/products/databases/tablesdb/type-generation', new: isNewUntil('31 Jul 2025') }, { label: 'Offline sync', - href: '/docs/products/databases/offline' + href: '/docs/products/databases/tablesdb/offline' }, { label: 'Bulk operations', - href: '/docs/products/databases/bulk-operations', + href: '/docs/products/databases/tablesdb/bulk-operations', new: isNewUntil('31 Jul 2025') }, { label: 'Atomic numeric operations', - href: '/docs/products/databases/atomic-numeric-operations', + href: '/docs/products/databases/tablesdb/atomic-numeric-operations', new: isNewUntil('31 Jul 2025') }, { label: 'CSV imports', - href: '/docs/products/databases/csv-imports', + href: '/docs/products/databases/tablesdb/csv-imports', new: isNewUntil('31 Jul 2025') }, { label: 'CSV exports', - href: '/docs/products/databases/csv-exports', + href: '/docs/products/databases/tablesdb/csv-exports', new: isNewUntil('28 Feb 2026') }, { label: 'AI suggestions', - href: '/docs/products/databases/ai-suggestions', + href: '/docs/products/databases/tablesdb/ai-suggestions', new: isNewUntil('31 Dec 2025') }, { label: 'Timestamp overrides', - href: '/docs/products/databases/timestamp-overrides' + href: '/docs/products/databases/tablesdb/timestamp-overrides' } ] }, @@ -145,16 +145,16 @@ const legacyUrl = $derived( page.url.pathname - .replace('/products/databases', '/products/databases/legacy') - .replace('rows', 'documents') - .replace('tables', 'collections') + .replace('/tablesdb/', '/tablesdb/legacy/') + .replace(/\/rows(\/|$)/, '/documents$1') + .replace(/\/tables(\/|$)/, '/collections$1') ); const hideSubtitleRoutes = ['offline', 'backups', 'csv-imports', 'csv-exports']; const shouldShowSubtitle = $derived( !hideSubtitleRoutes.some((segment) => page.route.id?.includes(segment)) && - !page.url.pathname.endsWith('products/databases') + !page.url.pathname.endsWith('products/databases/tablesdb') ); const headerSectionInfoAlert = writable(null); diff --git a/src/routes/docs/products/databases/+page.markdoc b/src/routes/docs/products/databases/tablesdb/+page.markdoc similarity index 70% rename from src/routes/docs/products/databases/+page.markdoc rename to src/routes/docs/products/databases/tablesdb/+page.markdoc index 9217bde1e68..e9f01089844 100644 --- a/src/routes/docs/products/databases/+page.markdoc +++ b/src/routes/docs/products/databases/tablesdb/+page.markdoc @@ -1,7 +1,7 @@ --- layout: article -title: Databases -description: Store and query structured data with Appwrite Databases. Databases provide performant and scalable storage for your application, business, and user data. +title: TablesDB +description: Store and query structured data with Appwrite TablesDB. Tables provide performant and scalable storage for your application, business, and user data. --- Appwrite Databases let you store and query structured data. @@ -14,6 +14,6 @@ Databases store data, if you need to store files like images, PDFs or videos, us You can organize data into databases, tables, and rows. You can also paginate, order, and query rows. For complex business logic, Appwrite supports relationships to help you model your data. -{% arrow_link href="/docs/products/databases/quick-start" %} +{% arrow_link href="/docs/products/databases/tablesdb/quick-start" %} Quick start {% /arrow_link %} \ No newline at end of file diff --git a/src/routes/docs/products/databases/ai-suggestions/+page.markdoc b/src/routes/docs/products/databases/tablesdb/ai-suggestions/+page.markdoc similarity index 100% rename from src/routes/docs/products/databases/ai-suggestions/+page.markdoc rename to src/routes/docs/products/databases/tablesdb/ai-suggestions/+page.markdoc diff --git a/src/routes/docs/products/databases/atomic-numeric-operations/+page.markdoc b/src/routes/docs/products/databases/tablesdb/atomic-numeric-operations/+page.markdoc similarity index 100% rename from src/routes/docs/products/databases/atomic-numeric-operations/+page.markdoc rename to src/routes/docs/products/databases/tablesdb/atomic-numeric-operations/+page.markdoc diff --git a/src/routes/docs/products/databases/backups/+page.markdoc b/src/routes/docs/products/databases/tablesdb/backups/+page.markdoc similarity index 100% rename from src/routes/docs/products/databases/backups/+page.markdoc rename to src/routes/docs/products/databases/tablesdb/backups/+page.markdoc diff --git a/src/routes/docs/products/databases/bulk-operations/+page.markdoc b/src/routes/docs/products/databases/tablesdb/bulk-operations/+page.markdoc similarity index 100% rename from src/routes/docs/products/databases/bulk-operations/+page.markdoc rename to src/routes/docs/products/databases/tablesdb/bulk-operations/+page.markdoc diff --git a/src/routes/docs/products/databases/csv-exports/+page.markdoc b/src/routes/docs/products/databases/tablesdb/csv-exports/+page.markdoc similarity index 100% rename from src/routes/docs/products/databases/csv-exports/+page.markdoc rename to src/routes/docs/products/databases/tablesdb/csv-exports/+page.markdoc diff --git a/src/routes/docs/products/databases/csv-imports/+page.markdoc b/src/routes/docs/products/databases/tablesdb/csv-imports/+page.markdoc similarity index 100% rename from src/routes/docs/products/databases/csv-imports/+page.markdoc rename to src/routes/docs/products/databases/tablesdb/csv-imports/+page.markdoc diff --git a/src/routes/docs/products/databases/databases/+page.markdoc b/src/routes/docs/products/databases/tablesdb/databases/+page.markdoc similarity index 100% rename from src/routes/docs/products/databases/databases/+page.markdoc rename to src/routes/docs/products/databases/tablesdb/databases/+page.markdoc diff --git a/src/routes/docs/products/databases/geo-queries/+page.markdoc b/src/routes/docs/products/databases/tablesdb/geo-queries/+page.markdoc similarity index 100% rename from src/routes/docs/products/databases/geo-queries/+page.markdoc rename to src/routes/docs/products/databases/tablesdb/geo-queries/+page.markdoc diff --git a/src/routes/docs/products/databases/legacy/+layout.svelte b/src/routes/docs/products/databases/tablesdb/legacy/+layout.svelte similarity index 100% rename from src/routes/docs/products/databases/legacy/+layout.svelte rename to src/routes/docs/products/databases/tablesdb/legacy/+layout.svelte diff --git a/src/routes/docs/products/databases/legacy/+page.ts b/src/routes/docs/products/databases/tablesdb/legacy/+page.ts similarity index 100% rename from src/routes/docs/products/databases/legacy/+page.ts rename to src/routes/docs/products/databases/tablesdb/legacy/+page.ts diff --git a/src/routes/docs/products/databases/legacy/atomic-numeric-operations/+page.markdoc b/src/routes/docs/products/databases/tablesdb/legacy/atomic-numeric-operations/+page.markdoc similarity index 100% rename from src/routes/docs/products/databases/legacy/atomic-numeric-operations/+page.markdoc rename to src/routes/docs/products/databases/tablesdb/legacy/atomic-numeric-operations/+page.markdoc diff --git a/src/routes/docs/products/databases/legacy/bulk-operations/+page.markdoc b/src/routes/docs/products/databases/tablesdb/legacy/bulk-operations/+page.markdoc similarity index 100% rename from src/routes/docs/products/databases/legacy/bulk-operations/+page.markdoc rename to src/routes/docs/products/databases/tablesdb/legacy/bulk-operations/+page.markdoc diff --git a/src/routes/docs/products/databases/legacy/collections/+page.markdoc b/src/routes/docs/products/databases/tablesdb/legacy/collections/+page.markdoc similarity index 100% rename from src/routes/docs/products/databases/legacy/collections/+page.markdoc rename to src/routes/docs/products/databases/tablesdb/legacy/collections/+page.markdoc diff --git a/src/routes/docs/products/databases/legacy/databases/+page.markdoc b/src/routes/docs/products/databases/tablesdb/legacy/databases/+page.markdoc similarity index 100% rename from src/routes/docs/products/databases/legacy/databases/+page.markdoc rename to src/routes/docs/products/databases/tablesdb/legacy/databases/+page.markdoc diff --git a/src/routes/docs/products/databases/legacy/documents/+page.markdoc b/src/routes/docs/products/databases/tablesdb/legacy/documents/+page.markdoc similarity index 100% rename from src/routes/docs/products/databases/legacy/documents/+page.markdoc rename to src/routes/docs/products/databases/tablesdb/legacy/documents/+page.markdoc diff --git a/src/routes/docs/products/databases/legacy/order/+page.markdoc b/src/routes/docs/products/databases/tablesdb/legacy/order/+page.markdoc similarity index 100% rename from src/routes/docs/products/databases/legacy/order/+page.markdoc rename to src/routes/docs/products/databases/tablesdb/legacy/order/+page.markdoc diff --git a/src/routes/docs/products/databases/legacy/pagination/+page.markdoc b/src/routes/docs/products/databases/tablesdb/legacy/pagination/+page.markdoc similarity index 100% rename from src/routes/docs/products/databases/legacy/pagination/+page.markdoc rename to src/routes/docs/products/databases/tablesdb/legacy/pagination/+page.markdoc diff --git a/src/routes/docs/products/databases/legacy/permissions/+page.markdoc b/src/routes/docs/products/databases/tablesdb/legacy/permissions/+page.markdoc similarity index 100% rename from src/routes/docs/products/databases/legacy/permissions/+page.markdoc rename to src/routes/docs/products/databases/tablesdb/legacy/permissions/+page.markdoc diff --git a/src/routes/docs/products/databases/legacy/queries/+page.markdoc b/src/routes/docs/products/databases/tablesdb/legacy/queries/+page.markdoc similarity index 100% rename from src/routes/docs/products/databases/legacy/queries/+page.markdoc rename to src/routes/docs/products/databases/tablesdb/legacy/queries/+page.markdoc diff --git a/src/routes/docs/products/databases/legacy/quick-start/+page.markdoc b/src/routes/docs/products/databases/tablesdb/legacy/quick-start/+page.markdoc similarity index 100% rename from src/routes/docs/products/databases/legacy/quick-start/+page.markdoc rename to src/routes/docs/products/databases/tablesdb/legacy/quick-start/+page.markdoc diff --git a/src/routes/docs/products/databases/legacy/relationships/+page.markdoc b/src/routes/docs/products/databases/tablesdb/legacy/relationships/+page.markdoc similarity index 100% rename from src/routes/docs/products/databases/legacy/relationships/+page.markdoc rename to src/routes/docs/products/databases/tablesdb/legacy/relationships/+page.markdoc diff --git a/src/routes/docs/products/databases/legacy/type-generation/+page.markdoc b/src/routes/docs/products/databases/tablesdb/legacy/type-generation/+page.markdoc similarity index 100% rename from src/routes/docs/products/databases/legacy/type-generation/+page.markdoc rename to src/routes/docs/products/databases/tablesdb/legacy/type-generation/+page.markdoc diff --git a/src/routes/docs/products/databases/offline/+page.markdoc b/src/routes/docs/products/databases/tablesdb/offline/+page.markdoc similarity index 100% rename from src/routes/docs/products/databases/offline/+page.markdoc rename to src/routes/docs/products/databases/tablesdb/offline/+page.markdoc diff --git a/src/routes/docs/products/databases/operators/+page.markdoc b/src/routes/docs/products/databases/tablesdb/operators/+page.markdoc similarity index 100% rename from src/routes/docs/products/databases/operators/+page.markdoc rename to src/routes/docs/products/databases/tablesdb/operators/+page.markdoc diff --git a/src/routes/docs/products/databases/order/+page.markdoc b/src/routes/docs/products/databases/tablesdb/order/+page.markdoc similarity index 100% rename from src/routes/docs/products/databases/order/+page.markdoc rename to src/routes/docs/products/databases/tablesdb/order/+page.markdoc diff --git a/src/routes/docs/products/databases/pagination/+page.markdoc b/src/routes/docs/products/databases/tablesdb/pagination/+page.markdoc similarity index 100% rename from src/routes/docs/products/databases/pagination/+page.markdoc rename to src/routes/docs/products/databases/tablesdb/pagination/+page.markdoc diff --git a/src/routes/docs/products/databases/permissions/+page.markdoc b/src/routes/docs/products/databases/tablesdb/permissions/+page.markdoc similarity index 100% rename from src/routes/docs/products/databases/permissions/+page.markdoc rename to src/routes/docs/products/databases/tablesdb/permissions/+page.markdoc diff --git a/src/routes/docs/products/databases/queries/+page.markdoc b/src/routes/docs/products/databases/tablesdb/queries/+page.markdoc similarity index 100% rename from src/routes/docs/products/databases/queries/+page.markdoc rename to src/routes/docs/products/databases/tablesdb/queries/+page.markdoc diff --git a/src/routes/docs/products/databases/quick-start/+page.markdoc b/src/routes/docs/products/databases/tablesdb/quick-start/+page.markdoc similarity index 100% rename from src/routes/docs/products/databases/quick-start/+page.markdoc rename to src/routes/docs/products/databases/tablesdb/quick-start/+page.markdoc diff --git a/src/routes/docs/products/databases/relationships/+page.markdoc b/src/routes/docs/products/databases/tablesdb/relationships/+page.markdoc similarity index 100% rename from src/routes/docs/products/databases/relationships/+page.markdoc rename to src/routes/docs/products/databases/tablesdb/relationships/+page.markdoc diff --git a/src/routes/docs/products/databases/rows/+page.markdoc b/src/routes/docs/products/databases/tablesdb/rows/+page.markdoc similarity index 100% rename from src/routes/docs/products/databases/rows/+page.markdoc rename to src/routes/docs/products/databases/tablesdb/rows/+page.markdoc diff --git a/src/routes/docs/products/databases/tables/+page.markdoc b/src/routes/docs/products/databases/tablesdb/tables/+page.markdoc similarity index 100% rename from src/routes/docs/products/databases/tables/+page.markdoc rename to src/routes/docs/products/databases/tablesdb/tables/+page.markdoc diff --git a/src/routes/docs/products/databases/timestamp-overrides/+page.markdoc b/src/routes/docs/products/databases/tablesdb/timestamp-overrides/+page.markdoc similarity index 100% rename from src/routes/docs/products/databases/timestamp-overrides/+page.markdoc rename to src/routes/docs/products/databases/tablesdb/timestamp-overrides/+page.markdoc diff --git a/src/routes/docs/products/databases/transactions/+page.markdoc b/src/routes/docs/products/databases/tablesdb/transactions/+page.markdoc similarity index 100% rename from src/routes/docs/products/databases/transactions/+page.markdoc rename to src/routes/docs/products/databases/tablesdb/transactions/+page.markdoc diff --git a/src/routes/docs/products/databases/type-generation/+page.markdoc b/src/routes/docs/products/databases/tablesdb/type-generation/+page.markdoc similarity index 100% rename from src/routes/docs/products/databases/type-generation/+page.markdoc rename to src/routes/docs/products/databases/tablesdb/type-generation/+page.markdoc diff --git a/src/routes/docs/products/databases/vectorsdb/+layout.svelte b/src/routes/docs/products/databases/vectorsdb/+layout.svelte new file mode 100644 index 00000000000..bd502da28b6 --- /dev/null +++ b/src/routes/docs/products/databases/vectorsdb/+layout.svelte @@ -0,0 +1,29 @@ + + + + + + {@render children()} + diff --git a/src/routes/docs/products/databases/vectorsdb/+page.markdoc b/src/routes/docs/products/databases/vectorsdb/+page.markdoc new file mode 100644 index 00000000000..f0391bc33d3 --- /dev/null +++ b/src/routes/docs/products/databases/vectorsdb/+page.markdoc @@ -0,0 +1,11 @@ +--- +layout: article +title: VectorsDB +description: Store vector embeddings and run similarity search with Appwrite VectorsDB to power semantic search, recommendations, and other AI features. +--- + +Appwrite VectorsDB stores vector embeddings and runs similarity search, so you can build semantic search, recommendations, and other AI features. It also exposes an endpoint to generate text embeddings, and shares the permissions, indexes, transactions, and realtime concepts used across Appwrite Databases. + +{% info title="Documentation in progress" %} +Detailed VectorsDB guides are on the way. For now, the concepts in [TablesDB](/docs/products/databases/tablesdb) are the closest reference. +{% /info %} From dcdb713fe1f5b386a098873c7ceb7cb22eccde39 Mon Sep 17 00:00:00 2001 From: Atharva Deosthale Date: Mon, 29 Jun 2026 20:12:49 +0530 Subject: [PATCH 2/8] Add DocumentsDB documentation section Add DocumentsDB docs (concepts and journeys) under databases/documentsdb, move TablesDB within the databases section with redirects from the previous URLs, and align the backups and bulk operations pages. --- .optimize-cache.json | 8 + src/redirects.json | 4 + .../databases/documentsdb/+layout.svelte | 64 +- .../databases/documentsdb/+page.markdoc | 15 +- .../atomic-numeric-operations/+page.markdoc | 867 ++++++++ .../documentsdb/backups/+page.markdoc | 89 + .../documentsdb/bulk-operations/+page.markdoc | 567 +++++ .../documentsdb/collections/+page.markdoc | 526 +++++ .../documentsdb/databases/+page.markdoc | 218 ++ .../documentsdb/documents/+page.markdoc | 1189 +++++++++++ .../databases/documentsdb/order/+page.markdoc | 336 +++ .../documentsdb/pagination/+page.markdoc | 540 +++++ .../documentsdb/permissions/+page.markdoc | 35 + .../documentsdb/queries/+page.markdoc | 1855 +++++++++++++++++ .../documentsdb/quick-start/+page.markdoc | 243 +++ .../timestamp-overrides/+page.markdoc | 1266 +++++++++++ .../documentsdb/transactions/+page.markdoc | 1274 +++++++++++ .../databases/tablesdb/backups/+page.markdoc | 14 +- .../tablesdb/bulk-operations/+page.markdoc | 42 +- .../databases/documentsdb/backup-policy.avif | Bin 0 -> 10913 bytes .../databases/documentsdb/backups-tab.avif | Bin 0 -> 26847 bytes .../documentsdb/create-database.avif | Bin 0 -> 31320 bytes .../documentsdb/dark/backup-policy.avif | Bin 0 -> 11350 bytes .../documentsdb/dark/backups-tab.avif | Bin 0 -> 28535 bytes .../documentsdb/dark/create-database.avif | Bin 0 -> 34142 bytes .../documentsdb/dark/manual-backup.avif | Bin 0 -> 10490 bytes .../databases/documentsdb/manual-backup.avif | Bin 0 -> 10120 bytes 27 files changed, 9119 insertions(+), 33 deletions(-) create mode 100644 src/routes/docs/products/databases/documentsdb/atomic-numeric-operations/+page.markdoc create mode 100644 src/routes/docs/products/databases/documentsdb/backups/+page.markdoc create mode 100644 src/routes/docs/products/databases/documentsdb/bulk-operations/+page.markdoc create mode 100644 src/routes/docs/products/databases/documentsdb/collections/+page.markdoc create mode 100644 src/routes/docs/products/databases/documentsdb/databases/+page.markdoc create mode 100644 src/routes/docs/products/databases/documentsdb/documents/+page.markdoc create mode 100644 src/routes/docs/products/databases/documentsdb/order/+page.markdoc create mode 100644 src/routes/docs/products/databases/documentsdb/pagination/+page.markdoc create mode 100644 src/routes/docs/products/databases/documentsdb/permissions/+page.markdoc create mode 100644 src/routes/docs/products/databases/documentsdb/queries/+page.markdoc create mode 100644 src/routes/docs/products/databases/documentsdb/quick-start/+page.markdoc create mode 100644 src/routes/docs/products/databases/documentsdb/timestamp-overrides/+page.markdoc create mode 100644 src/routes/docs/products/databases/documentsdb/transactions/+page.markdoc create mode 100644 static/images/docs/databases/documentsdb/backup-policy.avif create mode 100644 static/images/docs/databases/documentsdb/backups-tab.avif create mode 100644 static/images/docs/databases/documentsdb/create-database.avif create mode 100644 static/images/docs/databases/documentsdb/dark/backup-policy.avif create mode 100644 static/images/docs/databases/documentsdb/dark/backups-tab.avif create mode 100644 static/images/docs/databases/documentsdb/dark/create-database.avif create mode 100644 static/images/docs/databases/documentsdb/dark/manual-backup.avif create mode 100644 static/images/docs/databases/documentsdb/manual-backup.avif diff --git a/.optimize-cache.json b/.optimize-cache.json index f926af4a597..babde58ee40 100644 --- a/.optimize-cache.json +++ b/.optimize-cache.json @@ -1455,6 +1455,14 @@ "static/images/docs/databases/dark/scale-custom-policies.png": "0013e987e9b8b917cb9be4c28048f851f2d188f3bfa5ff17a11a7ac7cf9c3ade", "static/images/docs/databases/dark/scale-policies.png": "9ca9523f2e20e9aa993f0ad933cdf1dcd12adbaa35ecb2a0b8b3d2fd65877e1f", "static/images/docs/databases/databases.png": "0278a6bc5672684653f74bcf3c0d022fdd82a08d7a7fd438b28e21bd81b5e5d5", + "static/images/docs/databases/documentsdb/backup-policy.png": "913cacbe957847f8a71efa2d2e704754e52cf9c276dce8978f6c473a9ba6595b", + "static/images/docs/databases/documentsdb/backups-tab.png": "231163729496618d26863c6fa7ad88069875f78a3c320033d4bddc3c2f8da376", + "static/images/docs/databases/documentsdb/create-database.png": "49ba017dcec96631a87f924b13b6b93478add7b516cc62947e87230b5a0d5de1", + "static/images/docs/databases/documentsdb/dark/backup-policy.png": "a29fad13b50374b3de55824f1332fa4be9c2c7a0c4c63f550d03306ffd546551", + "static/images/docs/databases/documentsdb/dark/backups-tab.png": "dedb6cfcdd9217e814e58cb14db3d8309f53e3071cb9f12edd9a0d5f9bad1d7c", + "static/images/docs/databases/documentsdb/dark/create-database.png": "fe4c1340226d31fb3fa1d655563c9c8fdd150b4d0aac3e217fdd2af40718c272", + "static/images/docs/databases/documentsdb/dark/manual-backup.png": "880f077a3a598c35c9939a1cfcab4bc82a2a88e730be1b4157359657f0a47dcd", + "static/images/docs/databases/documentsdb/manual-backup.png": "0f3432e170b68503b00fac4cf65ed7c5e5a04f34031b5011fe1c80f1eda2bf1a", "static/images/docs/databases/manual-backup.png": "a5854158c5350e333ae14b699db4626c5c26e17b529f3acd137cfae8cb08e9c4", "static/images/docs/databases/pro-policy.png": "b0d35de73c334614dc3f644459dea2bbc56d0da3157db985f24897597ae26302", "static/images/docs/databases/restore.png": "97611c54c654631d2a86a8453a2ea3603c32e85888c065668e945eeeeb894df0", diff --git a/src/redirects.json b/src/redirects.json index 65ebd11afc0..bc286d8f2d0 100644 --- a/src/redirects.json +++ b/src/redirects.json @@ -948,6 +948,10 @@ "link": "/docs/products/databases/geo-queries", "redirect": "/docs/products/databases/tablesdb/geo-queries" }, + { + "link": "/docs/products/databases/legacy", + "redirect": "/docs/products/databases/tablesdb/legacy" + }, { "link": "/docs/products/databases/legacy/atomic-numeric-operations", "redirect": "/docs/products/databases/tablesdb/legacy/atomic-numeric-operations" diff --git a/src/routes/docs/products/databases/documentsdb/+layout.svelte b/src/routes/docs/products/databases/documentsdb/+layout.svelte index 3d2666cc56d..3f63cab9b0a 100644 --- a/src/routes/docs/products/databases/documentsdb/+layout.svelte +++ b/src/routes/docs/products/databases/documentsdb/+layout.svelte @@ -6,7 +6,7 @@ const parent: NavParent = { href: '/docs/products/databases', - label: 'Databases' + label: 'DocumentsDB' }; const navigation: NavTree = [ @@ -16,6 +16,68 @@ { label: 'Overview', href: '/docs/products/databases/documentsdb' + }, + { + label: 'Quick start', + href: '/docs/products/databases/documentsdb/quick-start' + } + ] + }, + { + label: 'Concepts', + items: [ + { + label: 'Databases', + href: '/docs/products/databases/documentsdb/databases' + }, + { + label: 'Collections', + href: '/docs/products/databases/documentsdb/collections' + }, + { + label: 'Documents', + href: '/docs/products/databases/documentsdb/documents' + }, + { + label: 'Permissions', + href: '/docs/products/databases/documentsdb/permissions' + }, + { + label: 'Queries', + href: '/docs/products/databases/documentsdb/queries' + }, + { + label: 'Order', + href: '/docs/products/databases/documentsdb/order' + }, + { + label: 'Backups', + href: '/docs/products/databases/documentsdb/backups' + } + ] + }, + { + label: 'Journeys', + items: [ + { + label: 'Pagination', + href: '/docs/products/databases/documentsdb/pagination' + }, + { + label: 'Transactions', + href: '/docs/products/databases/documentsdb/transactions' + }, + { + label: 'Bulk operations', + href: '/docs/products/databases/documentsdb/bulk-operations' + }, + { + label: 'Atomic numeric operations', + href: '/docs/products/databases/documentsdb/atomic-numeric-operations' + }, + { + label: 'Timestamp overrides', + href: '/docs/products/databases/documentsdb/timestamp-overrides' } ] } diff --git a/src/routes/docs/products/databases/documentsdb/+page.markdoc b/src/routes/docs/products/databases/documentsdb/+page.markdoc index 9c70cfae243..cb74d847aff 100644 --- a/src/routes/docs/products/databases/documentsdb/+page.markdoc +++ b/src/routes/docs/products/databases/documentsdb/+page.markdoc @@ -1,11 +1,18 @@ --- layout: article title: DocumentsDB -description: Store schemaless documents in collections with Appwrite DocumentsDB for flexible, JSON-style application data. +description: Store and query schemaless documents with Appwrite DocumentsDB. Collections give you flexible, JSON-style storage for your application, business, and user data. --- -Appwrite DocumentsDB stores schemaless documents in collections, giving you flexible, JSON-style data without a fixed schema. It shares the same permissions, indexes, queries, transactions, and realtime concepts as the rest of Appwrite Databases. +Appwrite DocumentsDB lets you store and query schemaless documents. +Collections hold documents as flexible JSON, so you can add fields as your data evolves without defining a schema up front. -{% info title="Documentation in progress" %} -Detailed DocumentsDB guides are on the way. For now, the concepts in [TablesDB](/docs/products/databases/tablesdb) are the closest reference. +{% info title="Looking for file storage?" %} +Databases store data, if you need to store files like images, PDFs or videos, use [Appwrite Storage](/docs/products/storage). {% /info %} + +You can organize data into databases, collections, and documents. You can also paginate, order, and query documents. + +{% arrow_link href="/docs/products/databases/documentsdb/quick-start" %} +Quick start +{% /arrow_link %} diff --git a/src/routes/docs/products/databases/documentsdb/atomic-numeric-operations/+page.markdoc b/src/routes/docs/products/databases/documentsdb/atomic-numeric-operations/+page.markdoc new file mode 100644 index 00000000000..9dd095b1a31 --- /dev/null +++ b/src/routes/docs/products/databases/documentsdb/atomic-numeric-operations/+page.markdoc @@ -0,0 +1,867 @@ +--- +layout: article +title: Atomic numeric operations +description: Safely increment and decrement numeric fields without race conditions. Perfect for counters, quotas, inventory, and usage metrics in high-concurrency applications. +--- + +Atomic numeric operations allow you to safely increase or decrease numeric fields without fetching the full document. This eliminates race conditions and reduces bandwidth usage when updating any numeric values that need to be modified atomically, such as counters, scores, balances, and other fast-moving numeric data. + +These operations work on numeric document fields, whether the value is an integer or a floating-point number. + +# How atomic operations work {% #how-atomic-operations-work %} + +Instead of the traditional read-modify-write pattern, atomic numeric operations use dedicated methods to modify values directly on the server. The server applies the change atomically under concurrency control and returns the new value. + +**Traditional approach:** +1. Fetch document → `{ likes: 42 }` +2. Update client-side → `likes: 43` +3. Write back → `{ likes: 43 }` + +**Atomic approach:** +1. Call `incrementDocumentAttribute()` with the attribute key and the value to increment by +2. Server applies atomically → `likes: 43` + +# When to use atomic operations {% #when-to-use-atomic-operations %} + +Atomic numeric operations work well for: + +- **Social features**: Likes, follows, comment counts +- **Usage metering**: API credits, storage quotas, request limits +- **Game state**: Scores, lives, currency, experience points +- **E-commerce**: Stock counts, inventory levels +- **Workflow tracking**: Retry counts, progress indicators +- **Rate limiting**: Request counters, usage tracking + +# Perform atomic operations {% #perform-atomic-operations %} + +Use the `incrementDocumentAttribute` and `decrementDocumentAttribute` methods to perform atomic numeric operations. The server will apply these changes atomically under concurrency control. + +## Increment a field {% #increment-field %} + +{% multicode %} +```client-web +import { Client, DocumentsDB } from "appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const documentsDB = new DocumentsDB(client); + +const result = await documentsDB.incrementDocumentAttribute({ + databaseId: '', + collectionId: '', + documentId: '', + attribute: 'likes', // attribute + value: 1 // value +}); +``` +```client-flutter +import 'package:appwrite/appwrite.dart'; + +final client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject(''); + +final documentsDB = DocumentsDB(client); + +final document = await documentsDB.incrementDocumentAttribute( + databaseId: '', + collectionId: '', + documentId: '', + attribute: 'likes', + value: 1 +); +``` +```client-apple +import Appwrite +import AppwriteModels + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + +let documentsDB = DocumentsDB(client) + +let document = try await documentsDB.incrementDocumentAttribute( + databaseId: "", + collectionId: "", + documentId: "", + attribute: "likes", + value: 1 +) +``` +```client-android-kotlin +import io.appwrite.Client +import io.appwrite.services.DocumentsDB + +val client = Client(applicationContext) + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + +val documentsDB = DocumentsDB(client) + +val document = documentsDB.incrementDocumentAttribute( + databaseId = "", + collectionId = "", + documentId = "", + attribute = "likes", + value = 1 +) +``` +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +const documentsDB = new sdk.DocumentsDB(client); + +const result = await documentsDB.incrementDocumentAttribute({ + databaseId: '', + collectionId: '', + documentId: '', + attribute: 'likes', // attribute + value: 1 // value +}); +``` +```server-python +from appwrite.client import Client +from appwrite.services.documents_db import DocumentsDB + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_key('') # Your secret API key + +documents_db = DocumentsDB(client) + +result = documents_db.increment_document_attribute( + database_id = '', + collection_id = '', + document_id = '', + attribute = 'likes', # attribute + value = 1 # value +) +``` +```rust +use appwrite::Client; +use appwrite::services::documents_db::DocumentsDB; + +let client = Client::new() + .set_endpoint("https://.cloud.appwrite.io/v1") + .set_project("") + .set_key(""); + +let documents_db = DocumentsDB::new(&client); + +let result = documents_db.increment_document_attribute( + "", + "", + "", + "likes", // attribute + Some(1.0), // value + None, // max + None, // transaction_id +).await?; +``` +```graphql +mutation { + documentsDBIncrementDocumentAttribute( + databaseId: "", + collectionId: "", + documentId: "", + attribute: "likes", + value: 1 + ) { + _id + _collectionId + _databaseId + _createdAt + _updatedAt + _permissions + data + } +} +``` +{% /multicode %} + +## Decrement a field {% #decrement-field %} + +Use the `decrementDocumentAttribute` method to decrease numeric fields: + +{% multicode %} +```client-web +import { Client, DocumentsDB } from "appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject(''); // Your project ID + +const documentsDB = new DocumentsDB(client); + +const result = await documentsDB.decrementDocumentAttribute({ + databaseId: '', + collectionId: '', + documentId: '', + attribute: 'credits', // attribute + value: 5 // value +}); +``` +```client-flutter +import 'package:appwrite/appwrite.dart'; + +final client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject(''); + +final documentsDB = DocumentsDB(client); + +final document = await documentsDB.decrementDocumentAttribute( + databaseId: '', + collectionId: '', + documentId: '', + attribute: 'credits', + value: 5 +); +``` +```client-apple +import Appwrite +import AppwriteModels + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + +let documentsDB = DocumentsDB(client) + +let document = try await documentsDB.decrementDocumentAttribute( + databaseId: "", + collectionId: "", + documentId: "", + attribute: "credits", + value: 5 +) +``` +```client-android-kotlin +import io.appwrite.Client +import io.appwrite.services.DocumentsDB + +val client = Client(applicationContext) + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + +val documentsDB = DocumentsDB(client) + +val document = documentsDB.decrementDocumentAttribute( + databaseId = "", + collectionId = "", + documentId = "", + attribute = "credits", + value = 5 +) +``` +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +const documentsDB = new sdk.DocumentsDB(client); + +const result = await documentsDB.decrementDocumentAttribute({ + databaseId: '', + collectionId: '', + documentId: '', + attribute: 'credits', // attribute + value: 5 // value +}); +``` +```server-python +from appwrite.client import Client +from appwrite.services.documents_db import DocumentsDB + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_key('') # Your secret API key + +documents_db = DocumentsDB(client) + +result = documents_db.decrement_document_attribute( + database_id = '', + collection_id = '', + document_id = '', + attribute = 'credits', # attribute + value = 5 # value +) +``` +```rust +use appwrite::Client; +use appwrite::services::documents_db::DocumentsDB; + +let client = Client::new() + .set_endpoint("https://.cloud.appwrite.io/v1") + .set_project("") + .set_key(""); + +let documents_db = DocumentsDB::new(&client); + +let result = documents_db.decrement_document_attribute( + "", + "", + "", + "credits", // attribute + Some(5.0), // value + None, // min + None, // transaction_id +).await?; +``` +```graphql +mutation { + documentsDBDecrementDocumentAttribute( + databaseId: "", + collectionId: "", + documentId: "", + attribute: "credits", + value: 5 + ) { + _id + _collectionId + _databaseId + _createdAt + _updatedAt + _permissions + data + } +} +``` +{% /multicode %} + +# Set constraints and bounds {% #set-constraints-and-bounds %} + +You can set minimum and maximum bounds for individual operations to prevent invalid values. Use the optional `min` and `max` parameters to ensure the final value stays within acceptable limits. If an operation would move the value past the bound, the request is rejected. + +## Example with constraints {% #example-with-constraints %} + +{% multicode %} +```client-web +// Increment with maximum constraint +const result = await documentsDB.incrementDocumentAttribute({ + databaseId: '', + collectionId: '', + documentId: '', + attribute: 'credits', // attribute + value: 100, // value + max: 1000 // max (optional) +}); + +// Decrement with minimum constraint +const result2 = await documentsDB.decrementDocumentAttribute({ + databaseId: '', + collectionId: '', + documentId: '', + attribute: 'credits', // attribute + value: 50, // value + min: 0 // min (optional) +}); +``` +```client-flutter +// Increment with maximum constraint +final document = await documentsDB.incrementDocumentAttribute( + databaseId: '', + collectionId: '', + documentId: '', + attribute: 'credits', + value: 100, + max: 1000 +); + +// Decrement with minimum constraint +final document2 = await documentsDB.decrementDocumentAttribute( + databaseId: '', + collectionId: '', + documentId: '', + attribute: 'credits', + value: 50, + min: 0 +); +``` +```client-apple +// Increment with maximum constraint +let document = try await documentsDB.incrementDocumentAttribute( + databaseId: "", + collectionId: "", + documentId: "", + attribute: "credits", + value: 100, + max: 1000 +) + +// Decrement with minimum constraint +let document2 = try await documentsDB.decrementDocumentAttribute( + databaseId: "", + collectionId: "", + documentId: "", + attribute: "credits", + value: 50, + min: 0 +) +``` +```client-android-kotlin +// Increment with maximum constraint +val document = documentsDB.incrementDocumentAttribute( + databaseId = "", + collectionId = "", + documentId = "", + attribute = "credits", + value = 100, + max = 1000 +) + +// Decrement with minimum constraint +val document2 = documentsDB.decrementDocumentAttribute( + databaseId = "", + collectionId = "", + documentId = "", + attribute = "credits", + value = 50, + min = 0 +) +``` +```server-nodejs +// Increment with maximum constraint +const result = await documentsDB.incrementDocumentAttribute({ + databaseId: '', + collectionId: '', + documentId: '', + attribute: 'credits', // attribute + value: 100, // value + max: 1000 // max (optional) +}); + +// Decrement with minimum constraint +const result2 = await documentsDB.decrementDocumentAttribute({ + databaseId: '', + collectionId: '', + documentId: '', + attribute: 'credits', // attribute + value: 50, // value + min: 0 // min (optional) +}); +``` +```server-python +# Increment with maximum constraint +result = documents_db.increment_document_attribute( + database_id = '', + collection_id = '', + document_id = '', + attribute = 'credits', # attribute + value = 100, # value + max = 1000 # max (optional) +) + +# Decrement with minimum constraint +result2 = documents_db.decrement_document_attribute( + database_id = '', + collection_id = '', + document_id = '', + attribute = 'credits', # attribute + value = 50, # value + min = 0 # min (optional) +) +``` +```rust +// Increment with maximum constraint +let result = documents_db.increment_document_attribute( + "", + "", + "", + "credits", // attribute + Some(100.0), // value + Some(1000.0), // max (optional) + None, // transaction_id +).await?; + +// Decrement with minimum constraint +let result2 = documents_db.decrement_document_attribute( + "", + "", + "", + "credits", // attribute + Some(50.0), // value + Some(0.0), // min (optional) + None, // transaction_id +).await?; +``` +{% /multicode %} + +# Follow best practices {% #follow-best-practices %} + +## Use for high-concurrency scenarios {% #use-for-high-concurrency-scenarios %} + +Atomic numeric operations are most beneficial when multiple users or processes might update the same numeric field simultaneously. + +## Combine with regular updates {% #combine-with-regular-updates %} + +For complex updates that include both atomic operations and regular field changes, you'll need to use separate API calls: + +{% multicode %} +```client-web +// First, increment the likes atomically +const likeResult = await documentsDB.incrementDocumentAttribute({ + databaseId: '', + collectionId: '', + documentId: '', + attribute: 'likes', // attribute + value: 1 // value +}); + +// Then, update other fields +const updateResult = await documentsDB.updateDocument({ + databaseId: '', + collectionId: '', + documentId: '', + data: { + lastLikedBy: userId, + lastLikedAt: new Date().toISOString() + } +}); +``` +```client-flutter +// First, increment the likes atomically +final likeResult = await documentsDB.incrementDocumentAttribute( + databaseId: '', + collectionId: '', + documentId: '', + attribute: 'likes', + value: 1 +); + +// Then, update other fields +final updateResult = await documentsDB.updateDocument( + databaseId: '', + collectionId: '', + documentId: '', + data: { + 'lastLikedBy': userId, + 'lastLikedAt': DateTime.now().toIso8601String() + } +); +``` +```client-apple +// First, increment the likes atomically +let likeResult = try await documentsDB.incrementDocumentAttribute( + databaseId: "", + collectionId: "", + documentId: "", + attribute: "likes", + value: 1 +) + +// Then, update other fields +let updateResult = try await documentsDB.updateDocument( + databaseId: "", + collectionId: "", + documentId: "", + data: [ + "lastLikedBy": userId, + "lastLikedAt": ISO8601DateFormatter().string(from: Date()) + ] +) +``` +```client-android-kotlin +// First, increment the likes atomically +val likeResult = documentsDB.incrementDocumentAttribute( + databaseId = "", + collectionId = "", + documentId = "", + attribute = "likes", + value = 1 +) + +// Then, update other fields +val updateResult = documentsDB.updateDocument( + databaseId = "", + collectionId = "", + documentId = "", + data = mapOf( + "lastLikedBy" to userId, + "lastLikedAt" to Instant.now().toString() + ) +) +``` +```server-nodejs +// First, increment the likes atomically +const likeResult = await documentsDB.incrementDocumentAttribute({ + databaseId: '', + collectionId: '', + documentId: '', + attribute: 'likes', // attribute + value: 1 // value +}); + +// Then, update other fields +const updateResult = await documentsDB.updateDocument({ + databaseId: '', + collectionId: '', + documentId: '', + data: { + lastLikedBy: userId, + lastLikedAt: new Date().toISOString() + } +}); +``` +```server-python +# First, increment the likes atomically +like_result = documents_db.increment_document_attribute( + database_id = '', + collection_id = '', + document_id = '', + attribute = 'likes', # attribute + value = 1 # value +) + +# Then, update other fields +update_result = documents_db.update_document( + database_id = '', + collection_id = '', + document_id = '', + data = { + 'lastLikedBy': user_id, + 'lastLikedAt': datetime.now().isoformat() + } +) +``` +```rust +use serde_json::json; + +// First, increment the likes atomically +let like_result = documents_db.increment_document_attribute( + "", + "", + "", + "likes", // attribute + Some(1.0), // value + None, // max + None, // transaction_id +).await?; + +// Then, update other fields +let update_result = documents_db.update_document( + "", + "", + "", + Some(json!({ + "lastLikedBy": user_id, + "lastLikedAt": chrono::Utc::now().to_rfc3339() + })), + None, // permissions + None, // transaction_id +).await?; +``` +{% /multicode %} + +# Use transactions {% #use-transactions %} + +Atomic numeric operations accept `transactionId`. When provided, increments/decrements are staged and applied on commit. + +{% multicode %} +```client-web +await documentsDB.incrementDocumentAttribute({ + databaseId: '', + collectionId: '', + documentId: '', + attribute: 'likes', + value: 1, + transactionId: '' +}); +``` +```client-flutter +await documentsDB.incrementDocumentAttribute( + databaseId: '', + collectionId: '', + documentId: '', + attribute: 'likes', + value: 1, + transactionId: '' +); +``` +```client-apple +try await documentsDB.incrementDocumentAttribute( + databaseId: "", + collectionId: "", + documentId: "", + attribute: "likes", + value: 1, + transactionId: "" +) +``` +```client-android-kotlin +documentsDB.incrementDocumentAttribute( + databaseId = "", + collectionId = "", + documentId = "", + attribute = "likes", + value = 1, + transactionId = "" +) +``` +```client-android-java +documentsDB.incrementDocumentAttribute( + "", + "", + "", + "likes", + 1, + "", + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return null; + } + System.out.println(result); + return null; + }) +); +``` +```client-react-native +await documentsDB.incrementDocumentAttribute({ + databaseId: '', + collectionId: '', + documentId: '', + attribute: 'likes', + value: 1, + transactionId: '' +}); +``` +```server-nodejs +await documentsDB.incrementDocumentAttribute({ + databaseId: '', + collectionId: '', + documentId: '', + attribute: 'likes', + value: 1, + transactionId: '' +}); +``` +```server-deno +await documentsDB.incrementDocumentAttribute({ + databaseId: '', + collectionId: '', + documentId: '', + attribute: 'likes', + value: 1, + transactionId: '' +}); +``` +```server-python +documents_db.increment_document_attribute( + database_id = '', + collection_id = '', + document_id = '', + attribute = 'likes', + value = 1, + transaction_id = '' +) +``` +```rust +documents_db.increment_document_attribute( + "", + "", + "", + "likes", + Some(1.0), + None, // max + Some(""), // transaction_id +).await?; +``` +```server-php +$documentsDB->incrementDocumentAttribute( + databaseId: '', + collectionId: '', + documentId: '', + attribute: 'likes', + value: 1, + transactionId: '' +); +``` +```server-ruby +documents_db.increment_document_attribute( + database_id: '', + collection_id: '', + document_id: '', + attribute: 'likes', + value: 1, + transaction_id: '' +) +``` +```server-dotnet +await documentsDB.IncrementDocumentAttribute( + databaseId: "", + collectionId: "", + documentId: "", + attribute: "likes", + value: 1, + transactionId: "" +); +``` +```server-dart +await documentsDB.incrementDocumentAttribute( + databaseId: '', + collectionId: '', + documentId: '', + attribute: 'likes', + value: 1, + transactionId: '' +); +``` +```server-swift +try await documentsDB.incrementDocumentAttribute( + databaseId: "", + collectionId: "", + documentId: "", + attribute: "likes", + value: 1, + transactionId: "" +) +``` +```server-kotlin +documentsDB.incrementDocumentAttribute( + databaseId = "", + collectionId = "", + documentId = "", + attribute = "likes", + value = 1, + transactionId = "" +) +``` +```server-java +documentsDB.incrementDocumentAttribute( + "", + "", + "", + "likes", + 1, + "", + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return null; + } + System.out.println(result); + return null; + }) +); +``` +{% /multicode %} + +## Explore related features + +- [Bulk operations](/docs/products/databases/documentsdb/bulk-operations) - Update multiple documents at once +- [Permissions](/docs/products/databases/documentsdb/permissions) - Control access to documents +- [Queries](/docs/products/databases/documentsdb/queries) - Find documents to update diff --git a/src/routes/docs/products/databases/documentsdb/backups/+page.markdoc b/src/routes/docs/products/databases/documentsdb/backups/+page.markdoc new file mode 100644 index 00000000000..a5930313c71 --- /dev/null +++ b/src/routes/docs/products/databases/documentsdb/backups/+page.markdoc @@ -0,0 +1,89 @@ +--- +layout: article +title: Backups +description: Learn how to back up and restore your DocumentsDB databases on Appwrite Cloud, ensuring data security and seamless recovery. +--- + +Appwrite Backups enable seamless, **encrypted** database backups on Cloud. +All backups are **hot** backups, ensuring zero downtime and fast recovery. + +{% info title="Backups are available on Appwrite Cloud for all Pro and Enterprise customers." %} +{% /info %} + +You manage backups from a database's **Backups** tab, where you can automate backups with policies or create manual backups on demand. + +{% only_dark %} +![Backups tab](/images/docs/databases/documentsdb/dark/backups-tab.avif) +{% /only_dark %} +{% only_light %} +![Backups tab](/images/docs/databases/documentsdb/backups-tab.avif) +{% /only_light %} + +# Backup policies {% #backup-policies %} + +Backup policies automate your backups on a schedule. To create one, open your database's **Backups** tab and click **Create policy**, then choose a preset policy or add a custom one. + +{% only_dark %} +![Create backup policy](/images/docs/databases/documentsdb/dark/backup-policy.avif) +{% /only_dark %} +{% only_light %} +![Create backup policy](/images/docs/databases/documentsdb/backup-policy.avif) +{% /only_light %} + +The available options depend on your plan: + +- On the **Pro** plan, you get a **Daily** backup policy retained for 7 days. +- On the **Enterprise** plan, you get access to additional preset policies and custom policies, where you control how often backups run and how long they are retained. + +Click **Create** to save the policy. Your database is now set up for automated backups. + +# Manual backups {% #manual-backups %} + +You can create an on-demand backup whenever necessary. In your database's **Backups** tab, click **Manual backup**, then click **Create**. + +{% only_dark %} +![Manual backup](/images/docs/databases/documentsdb/dark/manual-backup.avif) +{% /only_dark %} +{% only_light %} +![Manual backup](/images/docs/databases/documentsdb/manual-backup.avif) +{% /only_light %} + +Manual backups are retained until you delete them. Depending on the size of your database, the backup may take some time to complete. You can monitor its progress in the backups list. + +# Restoring backups {% #restoring-backups %} + +To restore a database, you need an existing backup. + +1. Open your database's **Backups** tab. +2. In the backups list, open the **Actions** menu for the backup you want to restore. +3. Click **Restore**. +4. Enter a name for the new database and an optional database ID. +5. Click **Restore**. + +Depending on the size of your database, the restoration may take some time. The restore creates a new database from the backup, leaving the original untouched. + +# Backup security & performance {% #backup-security-and-performance %} + +All backups created with Appwrite are: + +1. **Encrypted**: + All backups are securely encrypted to ensure your data remains protected at all times. + +2. **Remotely stored**: + Backups are stored in a remote location, providing an additional layer of security and ensuring your data is always recoverable. + +3. **Hot backups**: + Backups are hot, meaning they occur with zero downtime, allowing you to recover data quickly without interrupting your projects and services. + +# Best practices {% #best-practices %} + +To ensure your backups are robust and effective, consider the following best practices: + +1. **Schedule regular backups**: + Add backup policies based on the frequency of database changes. Daily backups are often sufficient for most use cases. + +2. **Retain critical backups longer**: + Use custom policies with longer retention to keep backups of critical data for extended periods, ensuring historical records are available when needed. + +3. **Optimize backup policies based on data sensitivity**: + Tailor your backup frequency and retention settings according to the sensitivity and importance of the data. diff --git a/src/routes/docs/products/databases/documentsdb/bulk-operations/+page.markdoc b/src/routes/docs/products/databases/documentsdb/bulk-operations/+page.markdoc new file mode 100644 index 00000000000..6522e3bde64 --- /dev/null +++ b/src/routes/docs/products/databases/documentsdb/bulk-operations/+page.markdoc @@ -0,0 +1,567 @@ +--- +layout: article +title: Bulk operations +description: Perform bulk operations on documents within your collections for efficient data handling. +--- + +Appwrite Databases supports bulk operations for documents, allowing you to create, update, or delete multiple documents in a single request. This can significantly improve performance for apps as it allows you to reduce the number of API calls needed while working with large data sets. + +Bulk operations can only be performed via the server-side SDKs. The client-side SDKs do not support bulk operations by design to prevent abuse and protect against unexpected costs. This ensures that only trusted server environments can perform large-scale data operations. + +For client applications that need bulk-like functionality, consider using [Appwrite Functions](/docs/products/functions) with proper rate limiting and validation. + +{% info title="Important notes" %} +Bulk operations trigger Functions, Webhooks, or Realtime events for each document manipulated. Rather than a single event for the entire bulk operation, each document generates a separate event on the existing realtime channels for its operation type. +{% /info %} + +# Atomic behavior {% #atomic-behavior %} + +Bulk operations in Appwrite are **atomic**, meaning they follow an all-or-nothing approach. Either all documents in your bulk request succeed, or all documents fail. + +This atomicity ensures: +- **Data consistency**: Your database remains in a consistent state even if some operations would fail. +- **Race condition prevention**: Multiple clients can safely perform bulk operations simultaneously. +- **Simplified error handling**: You only need to handle complete success or complete failure scenarios. + +For example, if you attempt to create 100 documents and one fails due to a validation error, none of the 100 documents will be created. + +# Plan limits {% #plan-limits %} + +Bulk operations have different limits based on your Appwrite plan: + +| Plan | Documents per request | +|------|----------------------| +| Free | 100 | +| Pro | 1,000 | + +These limits apply to all bulk operations including create, update, upsert, and delete operations. If you need higher limits than what the Pro plan offers, you can [inquire](/contact-us/enterprise) about a custom plan. + +# Create documents {% #create-documents %} + +You can create multiple documents in a single request using the `createDocuments` method. + +{% info title="Custom timestamps" %} +When creating, updating or upserting in bulk, you can set `$createdAt` and `$updatedAt` for each document in the payload. Values must be ISO 8601 date-time strings. If omitted, Appwrite sets them automatically. +{% /info %} + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const documentsDB = new sdk.DocumentsDB(client); + +const result = await documentsDB.createDocuments({ + databaseId: '', + collectionId: '', + documents: [ + { + $id: sdk.ID.unique(), + name: 'Document 1' + }, + { + $id: sdk.ID.unique(), + name: 'Document 2' + } + ] +}); +``` + +```server-python +from appwrite.client import Client +from appwrite.services.documents_db import DocumentsDB +from appwrite.id import ID + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') +client.set_project('') +client.set_key('') + +documents_db = DocumentsDB(client) + +result = documents_db.create_documents( + database_id = '', + collection_id = '', + documents = [ + { + '$id': ID.unique(), + 'name': 'Document 1' + }, + { + '$id': ID.unique(), + 'name': 'Document 2' + } + ] +) +``` + +```rust +use appwrite::Client; +use appwrite::services::documents_db::DocumentsDB; +use appwrite::id::ID; +use serde_json::json; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new() + .set_endpoint("https://.cloud.appwrite.io/v1") + .set_project("") + .set_key(""); + + let documents_db = DocumentsDB::new(&client); + + let result = documents_db.create_documents( + "", + "", + vec![ + json!({ + "$id": ID::unique(), + "name": "Document 1" + }), + json!({ + "$id": ID::unique(), + "name": "Document 2" + }), + ], + None, + ).await?; + + Ok(()) +} +``` +{% /multicode %} + +# Update documents {% #update-documents %} + +{% info title="Permissions required" %} +You must grant **update** permissions to users at the **collection level** before users can update documents. +[Learn more about permissions](/docs/products/databases/documentsdb/permissions) +{% /info %} + +You can update multiple documents in a single request using the `updateDocuments` method. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const documentsDB = new sdk.DocumentsDB(client); + +const result = await documentsDB.updateDocuments({ + databaseId: '', + collectionId: '', + data: { + status: 'published' + }, + queries: [ + sdk.Query.equal('status', 'draft') + ] +}); +``` + +```server-python +from appwrite.client import Client +from appwrite.services.documents_db import DocumentsDB +from appwrite.query import Query + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') +client.set_project('') +client.set_key('') + +documents_db = DocumentsDB(client) + +result = documents_db.update_documents( + database_id = '', + collection_id = '', + data = { + 'status': 'published' + }, + queries = [ + Query.equal('status', 'draft') + ] +) +``` + +```rust +use appwrite::Client; +use appwrite::services::documents_db::DocumentsDB; +use appwrite::query::Query; +use serde_json::json; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new() + .set_endpoint("https://.cloud.appwrite.io/v1") + .set_project("") + .set_key(""); + + let documents_db = DocumentsDB::new(&client); + + let result = documents_db.update_documents( + "", + "", + Some(json!({ + "status": "published" + })), + Some(vec![ + Query::equal("status", "draft").to_string(), + ]), + None, + ).await?; + + Ok(()) +} +``` +{% /multicode %} + +# Upsert documents {% #upsert-documents %} + +{% info title="Permissions required" %} +You must grant **create** and **update** permissions to users at the **collection level** before users can create documents. +[Learn more about permissions](/docs/products/databases/documentsdb/permissions) +{% /info %} + +You can upsert multiple documents in a single request using the `upsertDocuments` method. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const documentsDB = new sdk.DocumentsDB(client); + +const result = await documentsDB.upsertDocuments({ + databaseId: '', + collectionId: '', + documents: [ + { + $id: sdk.ID.unique(), + name: 'New Document 1' + }, + { + $id: 'document-id-2', // Existing document ID + name: 'New Document 2' + } + ] +}); +``` + +```server-python +from appwrite.client import Client +from appwrite.services.documents_db import DocumentsDB +from appwrite.id import ID + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') +client.set_project('') +client.set_key('') + +documents_db = DocumentsDB(client) + +result = documents_db.upsert_documents( + database_id = '', + collection_id = '', + documents = [ + { + '$id': ID.unique(), + 'name': 'New Document 1' + }, + { + '$id': 'document-id-2', # Existing document ID + 'name': 'New Document 2' + } + ] +) +``` + +```rust +use appwrite::Client; +use appwrite::services::documents_db::DocumentsDB; +use appwrite::id::ID; +use serde_json::json; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new() + .set_endpoint("https://.cloud.appwrite.io/v1") + .set_project("") + .set_key(""); + + let documents_db = DocumentsDB::new(&client); + + let result = documents_db.upsert_documents( + "", + "", + vec![ + json!({ + "$id": ID::unique(), + "name": "New Document 1" + }), + json!({ + "$id": "document-id-2", // Existing document ID + "name": "New Document 2" + }), + ], + None, + ).await?; + + Ok(()) +} +``` +{% /multicode %} + +# Delete documents {% #delete-documents %} + +{% info title="Permissions required" %} +You must grant **delete** permissions to users at the **collection level** before users can delete documents. +[Learn more about permissions](/docs/products/databases/documentsdb/permissions) +{% /info %} + +You can delete multiple documents in a single request using the `deleteDocuments` method. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const documentsDB = new sdk.DocumentsDB(client); + +const result = await documentsDB.deleteDocuments({ + databaseId: '', + collectionId: '', + queries: [ + sdk.Query.equal('status', 'archived') + ] +}); +``` + +```server-python +from appwrite.client import Client +from appwrite.services.documents_db import DocumentsDB +from appwrite.query import Query + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') +client.set_project('') +client.set_key('') + +documents_db = DocumentsDB(client) + +result = documents_db.delete_documents( + database_id = '', + collection_id = '', + queries = [ + Query.equal('status', 'archived') + ] +) +``` + +```rust +use appwrite::Client; +use appwrite::services::documents_db::DocumentsDB; +use appwrite::query::Query; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new() + .set_endpoint("https://.cloud.appwrite.io/v1") + .set_project("") + .set_key(""); + + let documents_db = DocumentsDB::new(&client); + + let result = documents_db.delete_documents( + "", + "", + Some(vec![ + Query::equal("status", "archived").to_string(), + ]), + None, + ).await?; + + Ok(()) +} +``` +{% /multicode %} + +{% info title="Queries for deletion" %} + +When deleting documents, you must specify queries to filter which documents to delete. +If no queries are provided, all documents in the collection will be deleted. +[Learn more about queries](/docs/products/databases/documentsdb/queries). + +{% /info %} + +# Use transactions {% #use-transactions %} + +All bulk operations accept `transactionId`. When provided, Appwrite stages the bulk request and applies it on commit. See [Transactions](/docs/products/databases/documentsdb/transactions). + +{% multicode %} +```server-nodejs +await documentsDB.createDocuments({ + databaseId: '', + collectionId: '', + documents: [ + { $id: sdk.ID.unique(), name: 'One' }, + { $id: sdk.ID.unique(), name: 'Two' } + ], + transactionId: '' +}); +``` +```server-python +documents_db.create_documents( + database_id = '', + collection_id = '', + documents = [ + { '$id': ID.unique(), 'name': 'One' }, + { '$id': ID.unique(), 'name': 'Two' } + ], + transaction_id = '' +) +``` +```server-deno +await documentsDB.createDocuments({ + databaseId: '', + collectionId: '', + documents: [ + { $id: sdk.ID.unique(), name: 'One' }, + { $id: sdk.ID.unique(), name: 'Two' } + ], + transactionId: '' +}); +``` +```server-php +$documentsDB->createDocuments( + databaseId: '', + collectionId: '', + documents: [ + [ '$id' => ID::unique(), 'name' => 'One' ], + [ '$id' => ID::unique(), 'name' => 'Two' ] + ], + transactionId: '' +); +``` +```server-ruby +documents_db.create_documents( + database_id: '', + collection_id: '', + documents: [ + { '$id' => ID.unique(), 'name' => 'One' }, + { '$id' => ID.unique(), 'name' => 'Two' } + ], + transaction_id: '' +) +``` +```server-dotnet +await documentsDB.CreateDocuments( + databaseId: "", + collectionId: "", + documents: new List> + { + new Dictionary + { + ["$id"] = ID.Unique(), + ["name"] = "One" + }, + new Dictionary + { + ["$id"] = ID.Unique(), + ["name"] = "Two" + } + }, + transactionId: "" +); +``` +```server-dart +await documentsDB.createDocuments( + databaseId: '', + collectionId: '', + documents: [ + { '\$id': ID.unique(), 'name': 'One' }, + { '\$id': ID.unique(), 'name': 'Two' } + ], + transactionId: '' +); +``` +```server-swift +try await documentsDB.createDocuments( + databaseId: "", + collectionId: "", + documents: [ + ["$id": ID.unique(), "name": "One"], + ["$id": ID.unique(), "name": "Two"] + ], + transactionId: "" +) +``` +```server-kotlin +documentsDB.createDocuments( + databaseId = "", + collectionId = "", + documents = listOf( + mapOf("\$id" to ID.unique(), "name" to "One"), + mapOf("\$id" to ID.unique(), "name" to "Two") + ), + transactionId = "" +) +``` +```server-java +documentsDB.createDocuments( + "", + "", + Arrays.asList( + Map.of( + "$id", ID.unique(), + "name", "One" + ), + Map.of( + "$id", ID.unique(), + "name", "Two" + ) + ), + "", + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return null; + } + System.out.println(result); + return null; + }) +); +``` +```rust +let result = documents_db.create_documents( + "", + "", + vec![ + json!({ + "$id": ID::unique(), + "name": "One" + }), + json!({ + "$id": ID::unique(), + "name": "Two" + }), + ], + Some(""), +).await?; +``` +{% /multicode %} diff --git a/src/routes/docs/products/databases/documentsdb/collections/+page.markdoc b/src/routes/docs/products/databases/documentsdb/collections/+page.markdoc new file mode 100644 index 00000000000..09ec098633d --- /dev/null +++ b/src/routes/docs/products/databases/documentsdb/collections/+page.markdoc @@ -0,0 +1,526 @@ +--- +layout: article +title: Collections +description: Organize documents with Appwrite DocumentsDB collections. Learn how to create collections, configure permissions, and add indexes for fast queries. +--- +Appwrite uses collections as containers of documents. +Collections are schemaless, so documents in the same collection can hold different fields. You shape data in your application instead of defining columns up front. + +# Create collection {% #create-collection %} +You can create collections using the Appwrite Console, a [Server SDK](/docs/sdks#server), or using the [CLI](/docs/tooling/command-line/installation). +{% tabs %} + +{% tabsitem #console title="Console" %} +Head to the **Databases** page, open a [database](/docs/products/databases/documentsdb/databases), and click **Create collection**. + +{% /tabsitem %} + +{% tabsitem #server-sdk title="Server SDK" %} +You can also create collections programmatically using a [Server SDK](/docs/sdks#server). Appwrite [Server SDKs](/docs/sdks#server) require an [API key](/docs/advanced/platform/api-keys). + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +const documentsDB = new sdk.DocumentsDB(client); + +const result = await documentsDB.createCollection({ + databaseId: '', + collectionId: '', + name: '', + permissions: [sdk.Permission.read(sdk.Role.any())], // optional + documentSecurity: false // optional +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +const documentsDB = new sdk.DocumentsDB(client); + +const result = await documentsDB.createCollection({ + databaseId: '', + collectionId: '', + name: '', + permissions: [sdk.Permission.read(sdk.Role.any())], // optional + documentSecurity: false // optional +}); +``` +```php +setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('') // Your project ID + ->setKey(''); // Your secret API key + +$documentsDB = new DocumentsDB($client); + +$result = $documentsDB->createCollection( + databaseId: '', + collectionId: '', + name: '', + permissions: [Permission::read(Role::any())], // optional + documentSecurity: false // optional +); +``` +```python +from appwrite.client import Client +from appwrite.services.documents_db import DocumentsDB +from appwrite.permission import Permission +from appwrite.role import Role + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_key('') # Your secret API key + +documents_db = DocumentsDB(client) + +result = documents_db.create_collection( + database_id = '', + collection_id = '', + name = '', + permissions = [Permission.read(Role.any())], # optional + document_security = False # optional +) +``` +```ruby +require 'appwrite' + +include Appwrite +include Appwrite::Permission +include Appwrite::Role + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('') # Your project ID + .set_key('') # Your secret API key + +documents_db = DocumentsDB.new(client) + +result = documents_db.create_collection( + database_id: '', + collection_id: '', + name: '', + permissions: [Permission.read(Role.any())], # optional + document_security: false # optional +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("") // Your project ID + .SetKey(""); // Your secret API key + +DocumentsDB documentsDB = new DocumentsDB(client); + +Collection result = await documentsDB.CreateCollection( + databaseId: "", + collectionId: "", + name: "", + permissions: new List { Permission.Read(Role.Any()) }, // optional + documentSecurity: false // optional +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; +import 'package:dart_appwrite/permission.dart'; +import 'package:dart_appwrite/role.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +DocumentsDB documentsDB = DocumentsDB(client); + +Collection result = await documentsDB.createCollection( + databaseId: '', + collectionId: '', + name: '', + permissions: [Permission.read(Role.any())], // (optional) + documentSecurity: false, // (optional) +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.Permission +import io.appwrite.Role +import io.appwrite.services.DocumentsDB + +val client = Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +val documentsDB = DocumentsDB(client) + +val response = documentsDB.createCollection( + databaseId = "", + collectionId = "", + name = "", + permissions = listOf(Permission.read(Role.any())), // optional + documentSecurity = false, // optional +) +``` +```java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.DocumentsDB; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey(""); // Your secret API key + +DocumentsDB documentsDB = new DocumentsDB(client); + +documentsDB.createCollection( + "", + "", + "", + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +let documentsDB = DocumentsDB(client) + +let collection = try await documentsDB.createCollection( + databaseId: "", + collectionId: "", + name: "", + permissions: [Permission.read(Role.any())], // optional + documentSecurity: false // optional +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::DocumentsDB; +use appwrite::permission::Permission; +use appwrite::role::Role; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new(); + client.set_endpoint("https://.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project(""); // Your project ID + client.set_key(""); // Your secret API key + + let documents_db = DocumentsDB::new(&client); + + let result = documents_db.create_collection( + "", + "", + "", + Some(vec![Permission::read(Role::any()).to_string()]), // permissions (optional) + Some(false), // documentSecurity (optional) + None, // enabled (optional) + None, // attributes (optional) + None, // indexes (optional) + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +{% /multicode %} +{% /tabsitem %} +{% /tabs %} + +# Permissions {% #permissions %} +Appwrite uses permissions to control data access. +For security, only users that are granted permissions can access a resource. + +By default, Appwrite doesn't grant permissions to any users when a new collection is created. +This means users can't create documents or read, update, and delete existing documents until you grant access. + +Set `documentSecurity` to `true` on a collection to configure permissions on individual documents. A user then needs either collection level or document level permissions to access a document. + +[Learn about configuring permissions](/docs/products/databases/documentsdb/permissions). + +# Indexes {% #indexes %} +Databases use indexes to quickly locate data without scanning every document. +To ensure the best performance, Appwrite recommends an index for every field you query. +If you plan to query multiple fields in a single query, creating an index with **all** queried fields will yield optimal performance. + +The following indexes are currently supported: + +| Type | Description | +|------------|--------------------------------------------------------------------------------------------------------------| +| `key` | Plain index to allow queries. | +| `unique` | Unique index to disallow duplicates. | +| `fulltext` | For searching within text fields. Required for the [search query method](/docs/products/databases/documentsdb/queries). | + +You can create an index by navigating to your collection's **Indexes** tab or by using your favorite [Server SDK](/docs/sdks#server). + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +const documentsDB = new sdk.DocumentsDB(client); + +const result = await documentsDB.createIndex({ + databaseId: '', + collectionId: '', + key: 'title_index', + type: sdk.DocumentsDBIndexType.Key, + attributes: ['title'] +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +const documentsDB = new sdk.DocumentsDB(client); + +const result = await documentsDB.createIndex({ + databaseId: '', + collectionId: '', + key: 'title_index', + type: sdk.DocumentsDBIndexType.Key, + attributes: ['title'] +}); +``` +```php +setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('') // Your project ID + ->setKey(''); // Your secret API key + +$documentsDB = new DocumentsDB($client); + +$result = $documentsDB->createIndex( + databaseId: '', + collectionId: '', + key: 'title_index', + type: DocumentsDBIndexType::KEY(), + attributes: ['title'] +); +``` +```python +from appwrite.client import Client +from appwrite.services.documents_db import DocumentsDB +from appwrite.enums import DocumentsDBIndexType + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_key('') # Your secret API key + +documents_db = DocumentsDB(client) + +result = documents_db.create_index( + database_id = '', + collection_id = '', + key = 'title_index', + type = DocumentsDBIndexType.KEY, + attributes = ['title'] +) +``` +```ruby +require 'appwrite' + +include Appwrite +include Appwrite::Enums + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('') # Your project ID + .set_key('') # Your secret API key + +documents_db = DocumentsDB.new(client) + +result = documents_db.create_index( + database_id: '', + collection_id: '', + key: 'title_index', + type: DocumentsDBIndexType::KEY, + attributes: ['title'] +) +``` +```csharp +using Appwrite; +using Appwrite.Enums; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("") // Your project ID + .SetKey(""); // Your secret API key + +DocumentsDB documentsDB = new DocumentsDB(client); + +Index result = await documentsDB.CreateIndex( + databaseId: "", + collectionId: "", + key: "title_index", + type: DocumentsDBIndexType.Key, + attributes: new List { "title" } +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; +import 'package:dart_appwrite/enums.dart' as enums; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +DocumentsDB documentsDB = DocumentsDB(client); + +Index result = await documentsDB.createIndex( + databaseId: '', + collectionId: '', + key: 'title_index', + type: enums.DocumentsDBIndexType.key, + attributes: ['title'], +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.enums.DocumentsDBIndexType +import io.appwrite.services.DocumentsDB + +val client = Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +val documentsDB = DocumentsDB(client) + +val response = documentsDB.createIndex( + databaseId = "", + collectionId = "", + key = "title_index", + type = DocumentsDBIndexType.KEY, + attributes = listOf("title"), +) +``` +```java +import io.appwrite.Client; +import io.appwrite.enums.DocumentsDBIndexType; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.DocumentsDB; +import java.util.List; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey(""); // Your secret API key + +DocumentsDB documentsDB = new DocumentsDB(client); + +documentsDB.createIndex( + "", + "", + "title_index", + DocumentsDBIndexType.KEY, + List.of("title"), + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite +import AppwriteEnums + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +let documentsDB = DocumentsDB(client) + +let index = try await documentsDB.createIndex( + databaseId: "", + collectionId: "", + key: "title_index", + type: .key, + attributes: ["title"] +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::DocumentsDB; +use appwrite::enums::DocumentsDBIndexType; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new(); + client.set_endpoint("https://.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project(""); // Your project ID + client.set_key(""); // Your secret API key + + let documents_db = DocumentsDB::new(&client); + + let result = documents_db.create_index( + "", + "", + "title_index", + DocumentsDBIndexType::Key, + vec!["title"], + None, // orders (optional) + None, // lengths (optional) + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +{% /multicode %} diff --git a/src/routes/docs/products/databases/documentsdb/databases/+page.markdoc b/src/routes/docs/products/databases/documentsdb/databases/+page.markdoc new file mode 100644 index 00000000000..f2f21db6e45 --- /dev/null +++ b/src/routes/docs/products/databases/documentsdb/databases/+page.markdoc @@ -0,0 +1,218 @@ +--- +layout: article +title: Databases +description: Dive deeper into Appwrite DocumentsDB and database configuration. Learn how to create and manage multiple databases for your application. +--- +Databases are the largest organizational unit in Appwrite. +Each database contains a group of [collections](/docs/products/databases/documentsdb/collections). + +# Create in Console {% #create-in-console %} +The easiest way to create a database is using the Appwrite Console. +Navigate to the **Databases** page and click **Create database**, choose **DocumentsDB** as the database type, and select your preferred tier. + +{% only_dark %} +![Create database](/images/docs/databases/documentsdb/dark/create-database.avif) +{% /only_dark %} +{% only_light %} +![Create database](/images/docs/databases/documentsdb/create-database.avif) +{% /only_light %} + +# Create using Server SDKs {% #create-using-server-sdks %} +You can programmatically create databases using a [Server SDK](/docs/sdks#server). Appwrite [Server SDKs](/docs/sdks#server) require an [API key](/docs/advanced/platform/api-keys). + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +const documentsDB = new sdk.DocumentsDB(client); + +const result = await documentsDB.create({ + databaseId: '', + name: '' +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +const documentsDB = new sdk.DocumentsDB(client); + +const result = await documentsDB.create({ + databaseId: '', + name: '' +}); +``` +```php +setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('') // Your project ID + ->setKey(''); // Your secret API key + +$documentsDB = new DocumentsDB($client); + +$result = $documentsDB->create( + databaseId: '', + name: '' +); +``` +```python +from appwrite.client import Client +from appwrite.services.documents_db import DocumentsDB + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_key('') # Your secret API key + +documents_db = DocumentsDB(client) + +result = documents_db.create( + database_id = '', + name = '' +) +``` +```ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('') # Your project ID + .set_key('') # Your secret API key + +documents_db = DocumentsDB.new(client) + +result = documents_db.create( + database_id: '', + name: '' +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("") // Your project ID + .SetKey(""); // Your secret API key + +DocumentsDB documentsDB = new DocumentsDB(client); + +Database result = await documentsDB.Create( + databaseId: "", + name: "" +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +DocumentsDB documentsDB = DocumentsDB(client); + +Database result = await documentsDB.create( + databaseId: '', + name: '', +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.services.DocumentsDB + +val client = Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +val documentsDB = DocumentsDB(client) + +val response = documentsDB.create( + databaseId = "", + name = "", +) +``` +```java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.DocumentsDB; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey(""); // Your secret API key + +DocumentsDB documentsDB = new DocumentsDB(client); + +documentsDB.create( + "", + "", + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +let documentsDB = DocumentsDB(client) + +let database = try await documentsDB.create( + databaseId: "", + name: "" +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::DocumentsDB; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new(); + client.set_endpoint("https://.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project(""); // Your project ID + client.set_key(""); // Your secret API key + + let documents_db = DocumentsDB::new(&client); + + let result = documents_db.create( + "", + "", + None, // enabled (optional) + None, // dedicatedDatabaseId (optional) + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +{% /multicode %} + diff --git a/src/routes/docs/products/databases/documentsdb/documents/+page.markdoc b/src/routes/docs/products/databases/documentsdb/documents/+page.markdoc new file mode 100644 index 00000000000..6bb47042249 --- /dev/null +++ b/src/routes/docs/products/databases/documentsdb/documents/+page.markdoc @@ -0,0 +1,1189 @@ +--- +layout: article +title: Documents +description: Create, read, update, and delete documents in Appwrite DocumentsDB. Learn how to work with schemaless JSON documents in your collections. +--- +Each piece of data in Appwrite DocumentsDB is a document. +Documents are schemaless JSON, so each document in a collection can hold its own set of fields. + +# Create documents {% #create-documents %} +{% info title="Permissions required" %} +You must grant _create_ permissions to users at the _collection level_ before users can create documents. +[Learn more about permissions](#permissions) +{% /info %} + +Use the `createDocument` method to add a document to a collection. Appwrite [Server SDKs](/docs/sdks#server) require an [API key](/docs/advanced/platform/api-keys). + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +const documentsDB = new sdk.DocumentsDB(client); + +const result = await documentsDB.createDocument({ + databaseId: '', + collectionId: '', + documentId: sdk.ID.unique(), + data: { title: 'Hamlet', year: 1601 }, + permissions: [sdk.Permission.read(sdk.Role.any())] // optional +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +const documentsDB = new sdk.DocumentsDB(client); + +const result = await documentsDB.createDocument({ + databaseId: '', + collectionId: '', + documentId: sdk.ID.unique(), + data: { title: 'Hamlet', year: 1601 }, + permissions: [sdk.Permission.read(sdk.Role.any())] // optional +}); +``` +```php +setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('') // Your project ID + ->setKey(''); // Your secret API key + +$documentsDB = new DocumentsDB($client); + +$result = $documentsDB->createDocument( + databaseId: '', + collectionId: '', + documentId: ID::unique(), + data: ['title' => 'Hamlet', 'year' => 1601], + permissions: [Permission::read(Role::any())] // optional +); +``` +```python +from appwrite.client import Client +from appwrite.services.documents_db import DocumentsDB +from appwrite.id import ID +from appwrite.permission import Permission +from appwrite.role import Role + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_key('') # Your secret API key + +documents_db = DocumentsDB(client) + +result = documents_db.create_document( + database_id = '', + collection_id = '', + document_id = ID.unique(), + data = { "title": "Hamlet", "year": 1601 }, + permissions = [Permission.read(Role.any())] # optional +) +``` +```ruby +require 'appwrite' + +include Appwrite +include Appwrite::Permission +include Appwrite::Role + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('') # Your project ID + .set_key('') # Your secret API key + +documents_db = DocumentsDB.new(client) + +result = documents_db.create_document( + database_id: '', + collection_id: '', + document_id: ID.unique(), + data: { "title" => "Hamlet", "year" => 1601 }, + permissions: [Permission.read(Role.any())] # optional +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("") // Your project ID + .SetKey(""); // Your secret API key + +DocumentsDB documentsDB = new DocumentsDB(client); + +Document result = await documentsDB.CreateDocument( + databaseId: "", + collectionId: "", + documentId: ID.Unique(), + data: new { title = "Hamlet", year = 1601 }, + permissions: new List { Permission.Read(Role.Any()) } // optional +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; +import 'package:dart_appwrite/permission.dart'; +import 'package:dart_appwrite/role.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +DocumentsDB documentsDB = DocumentsDB(client); + +Document result = await documentsDB.createDocument( + databaseId: '', + collectionId: '', + documentId: ID.unique(), + data: { "title": "Hamlet", "year": 1601 }, + permissions: [Permission.read(Role.any())], // (optional) +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.ID +import io.appwrite.Permission +import io.appwrite.Role +import io.appwrite.services.DocumentsDB + +val client = Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +val documentsDB = DocumentsDB(client) + +val response = documentsDB.createDocument( + databaseId = "", + collectionId = "", + documentId = ID.unique(), + data = mapOf("title" to "Hamlet", "year" to 1601), + permissions = listOf(Permission.read(Role.any())), // optional +) +``` +```java +import io.appwrite.Client; +import io.appwrite.ID; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.DocumentsDB; +import java.util.Map; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey(""); // Your secret API key + +DocumentsDB documentsDB = new DocumentsDB(client); + +documentsDB.createDocument( + "", + "", + ID.unique(), + Map.of("title", "Hamlet", "year", 1601), + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +let documentsDB = DocumentsDB(client) + +let document = try await documentsDB.createDocument( + databaseId: "", + collectionId: "", + documentId: ID.unique(), + data: ["title": "Hamlet", "year": 1601], + permissions: [Permission.read(Role.any())] // optional +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::DocumentsDB; +use appwrite::id::ID; +use appwrite::permission::Permission; +use appwrite::role::Role; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new(); + client.set_endpoint("https://.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project(""); // Your project ID + client.set_key(""); // Your secret API key + + let documents_db = DocumentsDB::new(&client); + + let result = documents_db.create_document( + "", + "", + ID::unique(), + serde_json::json!({ "title": "Hamlet", "year": 1601 }), + Some(vec![Permission::read(Role::any()).to_string()]), // optional + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite documents-db create-document \ + --database-id \ + --collection-id \ + --document-id 'unique()' \ + --data '{ "title": "Hamlet", "year": 1601 }' +``` +{% /multicode %} + +# List documents {% #list-documents %} +Use the `listDocuments` method to read documents from a collection. Pass [queries](/docs/products/databases/documentsdb/queries) to filter, order, and paginate the results. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +const documentsDB = new sdk.DocumentsDB(client); + +const result = await documentsDB.listDocuments({ + databaseId: '', + collectionId: '', + queries: [ + sdk.Query.equal('title', 'Hamlet') + ] +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +const documentsDB = new sdk.DocumentsDB(client); + +const result = await documentsDB.listDocuments({ + databaseId: '', + collectionId: '', + queries: [ + sdk.Query.equal('title', 'Hamlet') + ] +}); +``` +```php +setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('') // Your project ID + ->setKey(''); // Your secret API key + +$documentsDB = new DocumentsDB($client); + +$result = $documentsDB->listDocuments( + databaseId: '', + collectionId: '', + queries: [ + Query::equal('title', ['Hamlet']) + ] +); +``` +```python +from appwrite.client import Client +from appwrite.services.documents_db import DocumentsDB +from appwrite.query import Query + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_key('') # Your secret API key + +documents_db = DocumentsDB(client) + +result = documents_db.list_documents( + database_id = '', + collection_id = '', + queries = [ + Query.equal('title', 'Hamlet') + ] +) +``` +```ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('') # Your project ID + .set_key('') # Your secret API key + +documents_db = DocumentsDB.new(client) + +result = documents_db.list_documents( + database_id: '', + collection_id: '', + queries: [ + Query.equal('title', ['Hamlet']) + ] +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("") // Your project ID + .SetKey(""); // Your secret API key + +DocumentsDB documentsDB = new DocumentsDB(client); + +DocumentList result = await documentsDB.ListDocuments( + databaseId: "", + collectionId: "", + queries: new List { + Query.Equal("title", new List { "Hamlet" }) + } +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +DocumentsDB documentsDB = DocumentsDB(client); + +DocumentList result = await documentsDB.listDocuments( + databaseId: '', + collectionId: '', + queries: [ + Query.equal('title', 'Hamlet') + ], +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.Query +import io.appwrite.services.DocumentsDB + +val client = Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +val documentsDB = DocumentsDB(client) + +val response = documentsDB.listDocuments( + databaseId = "", + collectionId = "", + queries = listOf( + Query.equal("title", "Hamlet") + ), +) +``` +```java +import io.appwrite.Client; +import io.appwrite.Query; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.DocumentsDB; +import java.util.List; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey(""); // Your secret API key + +DocumentsDB documentsDB = new DocumentsDB(client); + +documentsDB.listDocuments( + "", + "", + List.of( + Query.equal("title", List.of("Hamlet")) + ), + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +let documentsDB = DocumentsDB(client) + +let documentList = try await documentsDB.listDocuments( + databaseId: "", + collectionId: "", + queries: [ + Query.equal("title", value: "Hamlet") + ] +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::DocumentsDB; +use appwrite::query::Query; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new(); + client.set_endpoint("https://.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project(""); // Your project ID + client.set_key(""); // Your secret API key + + let documents_db = DocumentsDB::new(&client); + + let result = documents_db.list_documents( + "", + "", + Some(vec![Query::equal("title", vec!["Hamlet"])]), + None, // transactionId (optional) + None, // total (optional) + None, // ttl (optional) + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite documents-db list-documents \ + --database-id \ + --collection-id \ + --queries '{"method":"equal","attribute":"title","values":["Hamlet"]}' +``` +{% /multicode %} + +# Update document {% #update-document %} +Use the `updateDocument` method to update a document. With the patch behavior, you only pass the fields you want to change. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +const documentsDB = new sdk.DocumentsDB(client); + +const result = await documentsDB.updateDocument({ + databaseId: '', + collectionId: '', + documentId: '', + data: { year: 1602 } +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +const documentsDB = new sdk.DocumentsDB(client); + +const result = await documentsDB.updateDocument({ + databaseId: '', + collectionId: '', + documentId: '', + data: { year: 1602 } +}); +``` +```php +setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('') // Your project ID + ->setKey(''); // Your secret API key + +$documentsDB = new DocumentsDB($client); + +$result = $documentsDB->updateDocument( + databaseId: '', + collectionId: '', + documentId: '', + data: ['year' => 1602] +); +``` +```python +from appwrite.client import Client +from appwrite.services.documents_db import DocumentsDB + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_key('') # Your secret API key + +documents_db = DocumentsDB(client) + +result = documents_db.update_document( + database_id = '', + collection_id = '', + document_id = '', + data = { "year": 1602 } +) +``` +```ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('') # Your project ID + .set_key('') # Your secret API key + +documents_db = DocumentsDB.new(client) + +result = documents_db.update_document( + database_id: '', + collection_id: '', + document_id: '', + data: { "year" => 1602 } +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("") // Your project ID + .SetKey(""); // Your secret API key + +DocumentsDB documentsDB = new DocumentsDB(client); + +Document result = await documentsDB.UpdateDocument( + databaseId: "", + collectionId: "", + documentId: "", + data: new { year = 1602 } +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +DocumentsDB documentsDB = DocumentsDB(client); + +Document result = await documentsDB.updateDocument( + databaseId: '', + collectionId: '', + documentId: '', + data: { "year": 1602 }, +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.services.DocumentsDB + +val client = Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +val documentsDB = DocumentsDB(client) + +val response = documentsDB.updateDocument( + databaseId = "", + collectionId = "", + documentId = "", + data = mapOf("year" to 1602), +) +``` +```java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.DocumentsDB; +import java.util.Map; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey(""); // Your secret API key + +DocumentsDB documentsDB = new DocumentsDB(client); + +documentsDB.updateDocument( + "", + "", + "", + Map.of("year", 1602), + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +let documentsDB = DocumentsDB(client) + +let document = try await documentsDB.updateDocument( + databaseId: "", + collectionId: "", + documentId: "", + data: ["year": 1602] +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::DocumentsDB; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new(); + client.set_endpoint("https://.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project(""); // Your project ID + client.set_key(""); // Your secret API key + + let documents_db = DocumentsDB::new(&client); + + let result = documents_db.update_document( + "", + "", + "", + Some(serde_json::json!({ "year": 1602 })), + None, // permissions (optional) + None, // transactionId (optional) + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite documents-db update-document \ + --database-id \ + --collection-id \ + --document-id \ + --data '{ "year": 1602 }' +``` +{% /multicode %} + +# Upsert documents {% #upsert-documents %} +Use the `upsertDocument` method to create a document if it doesn't exist, or update it if it does. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +const documentsDB = new sdk.DocumentsDB(client); + +const result = await documentsDB.upsertDocument({ + databaseId: '', + collectionId: '', + documentId: '', + data: { title: 'Hamlet', year: 1603 } +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +const documentsDB = new sdk.DocumentsDB(client); + +const result = await documentsDB.upsertDocument({ + databaseId: '', + collectionId: '', + documentId: '', + data: { title: 'Hamlet', year: 1603 } +}); +``` +```php +setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('') // Your project ID + ->setKey(''); // Your secret API key + +$documentsDB = new DocumentsDB($client); + +$result = $documentsDB->upsertDocument( + databaseId: '', + collectionId: '', + documentId: '', + data: ['title' => 'Hamlet', 'year' => 1603] +); +``` +```python +from appwrite.client import Client +from appwrite.services.documents_db import DocumentsDB + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_key('') # Your secret API key + +documents_db = DocumentsDB(client) + +result = documents_db.upsert_document( + database_id = '', + collection_id = '', + document_id = '', + data = { "title": "Hamlet", "year": 1603 } +) +``` +```ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('') # Your project ID + .set_key('') # Your secret API key + +documents_db = DocumentsDB.new(client) + +result = documents_db.upsert_document( + database_id: '', + collection_id: '', + document_id: '', + data: { "title" => "Hamlet", "year" => 1603 } +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("") // Your project ID + .SetKey(""); // Your secret API key + +DocumentsDB documentsDB = new DocumentsDB(client); + +Document result = await documentsDB.UpsertDocument( + databaseId: "", + collectionId: "", + documentId: "", + data: new { title = "Hamlet", year = 1603 } +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +DocumentsDB documentsDB = DocumentsDB(client); + +Document result = await documentsDB.upsertDocument( + databaseId: '', + collectionId: '', + documentId: '', + data: { "title": "Hamlet", "year": 1603 }, +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.services.DocumentsDB + +val client = Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +val documentsDB = DocumentsDB(client) + +val response = documentsDB.upsertDocument( + databaseId = "", + collectionId = "", + documentId = "", + data = mapOf("title" to "Hamlet", "year" to 1603), +) +``` +```java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.DocumentsDB; +import java.util.Map; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey(""); // Your secret API key + +DocumentsDB documentsDB = new DocumentsDB(client); + +documentsDB.upsertDocument( + "", + "", + "", + Map.of("title", "Hamlet", "year", 1603), + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +let documentsDB = DocumentsDB(client) + +let document = try await documentsDB.upsertDocument( + databaseId: "", + collectionId: "", + documentId: "", + data: ["title": "Hamlet", "year": 1603] +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::DocumentsDB; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new(); + client.set_endpoint("https://.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project(""); // Your project ID + client.set_key(""); // Your secret API key + + let documents_db = DocumentsDB::new(&client); + + let result = documents_db.upsert_document( + "", + "", + "", + Some(serde_json::json!({ "title": "Hamlet", "year": 1603 })), + None, // permissions (optional) + None, // transactionId (optional) + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite documents-db upsert-document \ + --database-id \ + --collection-id \ + --document-id \ + --data '{ "title": "Hamlet", "year": 1603 }' +``` +{% /multicode %} + +# Delete document {% #delete-document %} +Use the `deleteDocument` method to remove a document from a collection. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +const documentsDB = new sdk.DocumentsDB(client); + +const result = await documentsDB.deleteDocument({ + databaseId: '', + collectionId: '', + documentId: '' +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +const documentsDB = new sdk.DocumentsDB(client); + +const result = await documentsDB.deleteDocument({ + databaseId: '', + collectionId: '', + documentId: '' +}); +``` +```php +setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('') // Your project ID + ->setKey(''); // Your secret API key + +$documentsDB = new DocumentsDB($client); + +$result = $documentsDB->deleteDocument( + databaseId: '', + collectionId: '', + documentId: '' +); +``` +```python +from appwrite.client import Client +from appwrite.services.documents_db import DocumentsDB + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('') # Your project ID +client.set_key('') # Your secret API key + +documents_db = DocumentsDB(client) + +result = documents_db.delete_document( + database_id = '', + collection_id = '', + document_id = '' +) +``` +```ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('') # Your project ID + .set_key('') # Your secret API key + +documents_db = DocumentsDB.new(client) + +result = documents_db.delete_document( + database_id: '', + collection_id: '', + document_id: '' +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("") // Your project ID + .SetKey(""); // Your secret API key + +DocumentsDB documentsDB = new DocumentsDB(client); + +await documentsDB.DeleteDocument( + databaseId: "", + collectionId: "", + documentId: "" +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('') // Your project ID + .setKey(''); // Your secret API key + +DocumentsDB documentsDB = DocumentsDB(client); + +await documentsDB.deleteDocument( + databaseId: '', + collectionId: '', + documentId: '', +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.services.DocumentsDB + +val client = Client(context) + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +val documentsDB = DocumentsDB(client) + +documentsDB.deleteDocument( + databaseId = "", + collectionId = "", + documentId = "", +) +``` +```java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.DocumentsDB; + +Client client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey(""); // Your secret API key + +DocumentsDB documentsDB = new DocumentsDB(client); + +documentsDB.deleteDocument( + "", + "", + "", + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println("Deleted"); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("") // Your project ID + .setKey("") // Your secret API key + +let documentsDB = DocumentsDB(client) + +try await documentsDB.deleteDocument( + databaseId: "", + collectionId: "", + documentId: "" +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::DocumentsDB; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new(); + client.set_endpoint("https://.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project(""); // Your project ID + client.set_key(""); // Your secret API key + + let documents_db = DocumentsDB::new(&client); + + documents_db.delete_document( + "", + "", + "", + None, // transactionId (optional) + ).await?; + + Ok(()) +} +``` +```bash +appwrite documents-db delete-document \ + --database-id \ + --collection-id \ + --document-id +``` +{% /multicode %} + +# Permissions {% #permissions %} +To access documents through a [Client SDK](/docs/sdks#client), you must grant the relevant permissions. +By default, Appwrite doesn't grant any user permissions when a new collection is created. + +You can configure permissions at the collection level, or enable `documentSecurity` on the collection to also set permissions on individual documents. + +[Learn about configuring permissions](/docs/products/databases/documentsdb/permissions). diff --git a/src/routes/docs/products/databases/documentsdb/order/+page.markdoc b/src/routes/docs/products/databases/documentsdb/order/+page.markdoc new file mode 100644 index 00000000000..c8dfeba16c6 --- /dev/null +++ b/src/routes/docs/products/databases/documentsdb/order/+page.markdoc @@ -0,0 +1,336 @@ +--- +layout: article +title: Order +description: Understand how to do data ordering in Appwrite Databases. Learn how to order and sort your database records for efficient data retrieval. +--- + +You can order results returned by Appwrite Databases by using an order query. +For best performance, create an [index](/docs/products/databases/documentsdb/collections#indexes) on the field you plan to order by. + +# Ordering one field {% #one-field %} + +When querying using the [listDocuments](/docs/products/databases/documentsdb/documents#list-documents) endpoint, +you can specify the order of the documents returned using the `Query.orderAsc()` and `Query.orderDesc()` query methods. + +{% multicode %} +```client-web +import { Client, Query, DocumentsDB } from "appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject(''); + +const documentsDB = new DocumentsDB(client); + +documentsDB.listDocuments({ + databaseId: '', + collectionId: '', + queries: [ + Query.orderAsc('title'), + ] +}); +``` + +```client-flutter +import 'package:appwrite/appwrite.dart'; + +void main() async { + final client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject(''); + + final documentsDB = DocumentsDB(client); + + try { + final documents = await documentsDB.listDocuments( + databaseId: '', + collectionId: '', + queries: [ + Query.orderAsc('title') + ] + ); + } on AppwriteException catch(e) { + print(e); + } +} +``` + +```client-apple +import Appwrite +import AppwriteModels + +func main() async throws { + let client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject(''); + + let documentsDB = DocumentsDB(client) + + do { + let documents = try await documentsDB.listDocuments( + databaseId: "", + collectionId: "", + queries: [ + Query.orderAsc("title") + ] + ) + } catch { + print(error.localizedDescription) + } +} +``` +```client-android-kotlin +import io.appwrite.Client +import io.appwrite.Query +import io.appwrite.services.DocumentsDB + +suspend fun main() { + val client = Client(applicationContext) + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject(''); + + val documentsDB = DocumentsDB(client) + + try { + val documents = documentsDB.listDocuments( + databaseId = "", + collectionId = "", + queries = [ + Query.orderAsc("title") + ] + ) + } catch (e: AppwriteException) { + Log.e("Appwrite", e.message) + } +} +``` + +```graphql +query { + documentsDBListDocuments( + databaseId: "", + collectionId: "" + queries: ["orderAsc(\"title\")"] + ) { + total + documents { + _id + data + } + } +} +``` + +{% /multicode %} + +# Multiple fields {% #multiple-fields %} +To sort based on multiple fields, simply provide multiple query methods. +For better performance, create an index on the first field that you order by. + +In the example below, the movies returned will be first sorted by `title` in ascending order, then sorted by `year` in descending order. +{% multicode %} + +```js +// Web SDK code example for sorting based on multiple fields +// ... + +// List documents and sort based on multiple fields +documentsDB.listDocuments({ + databaseId: '', + collectionId: '', + queries: [ + Query.orderAsc('title'), // Order first by title in ascending order + Query.orderDesc('year'), // Then, order by year in descending order + ] +}); +``` +```dart +// Flutter SDK code example for sorting based on multiple fields +// ... + +// List documents and sort based on multiple fields +try { + final documents = await documentsDB.listDocuments( + databaseId: '', + collectionId: '', + queries: [ + Query.orderAsc('title'), // Order by title in ascending order + Query.orderDesc('year') // Order by year in descending order + ] + ); +} on AppwriteException catch(e) { + print(e); +} +``` +```kotlin +// Android SDK code example for sorting based on multiple fields +// ... + +// List documents and sort based on multiple fields +try { + val documents = documentsDB.listDocuments( + databaseId = "", + collectionId = "", + queries = [ + Query.orderAsc("title"), // Order by title in ascending order + Query.orderDesc("year") // Order by year in descending order + ] + ); +} catch (e: AppwriteException) { + Log.e("Appwrite", e.message); +} +``` +```swift +// Apple SDK code example for sorting based on multiple fields +// ... + +// List documents and sort based on multiple fields +do { + let documents = try await documentsDB.listDocuments( + databaseId: "", + collectionId: "", + queries: [ + Query.orderAsc("title"), // Order by title in ascending order + Query.orderDesc("year") // Order by year in descending order + ] + ); +} catch { + print(error.localizedDescription); +} +``` +```graphql +query { + documentsDBListDocuments( + databaseId: "", + collectionId: "", + queries: ["orderAsc(\"title\")", "orderDesc(\"year\")"] + ) { + total + documents { + _id + data + } + } +} +``` +{% /multicode %} + +# Ordering by sequence {% #sequence-ordering %} + +For ordering based on insertion order, you can use the `$sequence` field, which Appwrite automatically adds to all documents. Sorting by `$sequence` returns documents in the order they were created. + +{% multicode %} +```client-web +import { Client, Query, DocumentsDB } from "appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject(''); + +const documentsDB = new DocumentsDB(client); + +documentsDB.listDocuments({ + databaseId: '', + collectionId: '', + queries: [ + Query.orderAsc('$sequence'), + ] +}); +``` + +```client-flutter +import 'package:appwrite/appwrite.dart'; + +void main() async { + final client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject(''); + + final documentsDB = DocumentsDB(client); + + try { + final documents = await documentsDB.listDocuments( + databaseId: '', + collectionId: '', + queries: [ + Query.orderAsc('\$sequence') + ] + ); + } on AppwriteException catch(e) { + print(e); + } +} +``` + +```client-apple +import Appwrite +import AppwriteModels + +func main() async throws { + let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + + let documentsDB = DocumentsDB(client) + + do { + let documents = try await documentsDB.listDocuments( + databaseId: "", + collectionId: "", + queries: [ + Query.orderAsc("$sequence") + ] + ) + } catch { + print(error.localizedDescription) + } +} +``` + +```client-android-kotlin +import io.appwrite.Client +import io.appwrite.Query +import io.appwrite.services.DocumentsDB + +suspend fun main() { + val client = Client(applicationContext) + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + + val documentsDB = DocumentsDB(client) + + try { + val documents = documentsDB.listDocuments( + databaseId = "", + collectionId = "", + queries = listOf( + Query.orderAsc("\$sequence") + ) + ) + } catch (e: AppwriteException) { + Log.e("Appwrite", e.message) + } +} +``` + +```graphql +query { + documentsDBListDocuments( + databaseId: "", + collectionId: "" + queries: ["orderAsc(\"$sequence\")"] + ) { + total + documents { + _id + data + } + } +} +``` +{% /multicode %} + +The `$sequence` field is useful when you need: +- Consistent ordering for pagination, especially with high-frequency inserts +- Reliable insertion order tracking when timestamps might not be precise enough +- Simple insertion-order sorting without managing custom counter fields diff --git a/src/routes/docs/products/databases/documentsdb/pagination/+page.markdoc b/src/routes/docs/products/databases/documentsdb/pagination/+page.markdoc new file mode 100644 index 00000000000..1f310e8ffeb --- /dev/null +++ b/src/routes/docs/products/databases/documentsdb/pagination/+page.markdoc @@ -0,0 +1,540 @@ +--- +layout: article +title: Pagination +description: Implement pagination for large data sets in Appwrite Databases. Explore techniques for splitting and displaying data across multiple pages. +--- + +As your collection grows in size, you'll need to paginate the documents returned. +Pagination improves performance by returning a subset of documents that match a query at a time, called a page. + +By default, list operations return 25 documents per page, which can be changed using the `Query.limit()` query method. +There is no hard limit on the number of documents you can request. However, beware that **large pages can degrade performance**. + +# Offset pagination {% #offset-pagination %} + +Offset pagination divides documents into pages of `N` documents each. +To read page number `P`, skip `offset = N * (P - 1)` documents, then read the next `N`. + +Using `Query.limit()` and `Query.offset()` you can achieve offset pagination. +With `Query.limit()` you define how many documents can be returned from one request. +The `Query.offset()` is the number of documents you wish to skip before selecting documents. + +{% multicode %} +```client-web +import { Client, Query, DocumentsDB } from "appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject(''); + +const documentsDB = new DocumentsDB(client); + +// Page 1 +const page1 = await documentsDB.listDocuments({ + databaseId: '', + collectionId: '', + queries: [ + Query.limit(25), + Query.offset(0) + ] +}); + +// Page 2 +const page2 = await documentsDB.listDocuments({ + databaseId: '', + collectionId: '', + queries: [ + Query.limit(25), + Query.offset(25) + ] +}); +``` +```client-flutter +import 'package:appwrite/appwrite.dart'; + +void main() async { + final client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject(''); + + final documentsDB = DocumentsDB(client); + + final page1 = await documentsDB.listDocuments( + databaseId: '', + collectionId: '', + queries: [ + Query.limit(25), + Query.offset(0) + ] + ); + + final page2 = await documentsDB.listDocuments( + databaseId: '', + collectionId: '', + queries: [ + Query.limit(25), + Query.offset(25) + ] + ); +} +``` +```client-apple +import Appwrite +import AppwriteModels + +func main() async throws { + let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + + let documentsDB = DocumentsDB(client) + + let page1 = try await documentsDB.listDocuments( + databaseId: "", + collectionId: "", + queries: [ + Query.limit(25), + Query.offset(0) + ] + ) + + let page2 = try await documentsDB.listDocuments( + databaseId: "", + collectionId: "", + queries: [ + Query.limit(25), + Query.offset(25) + ] + ) +} +``` +```client-android-kotlin +import io.appwrite.Client +import io.appwrite.Query +import io.appwrite.services.DocumentsDB + +suspend fun main() { + val client = Client(applicationContext) + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + + val documentsDB = DocumentsDB(client) + + val page1 = documentsDB.listDocuments( + databaseId = "", + collectionId = "", + queries = listOf( + Query.limit(25), + Query.offset(0) + ) + ) + + val page2 = documentsDB.listDocuments( + databaseId = "", + collectionId = "", + queries = listOf( + Query.limit(25), + Query.offset(25) + ) + ) +} +``` + +{% /multicode %} + +{% info title="Drawbacks" %} +While traditional offset pagination is familiar, it comes with some drawbacks. +The request gets slower as the offset increases because the database has to skip over all the preceding documents before it can start selecting data. +If the data changes frequently, offset pagination will also produce **missing and duplicate** results. +{% /info %} + +# Cursor pagination {% #cursor-pagination %} + +The cursor is a unique identifier for a document that points to where the next page should start. +After reading a page of documents, pass the last document's ID into the `Query.cursorAfter(lastId)` query method to get the next page of documents. +Pass the first document's ID into the `Query.cursorBefore(firstId)` query method to retrieve the previous page. + +{% multicode %} + +```client-web +import { Client, Query, DocumentsDB } from "appwrite"; + +const client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject(""); + +const documentsDB = new DocumentsDB(client); + +// Page 1 +const page1 = await documentsDB.listDocuments({ + databaseId: '', + collectionId: '', + queries: [ + Query.limit(25) + ] +}); + +const lastId = page1.documents[page1.documents.length - 1].$id; + +// Page 2 +const page2 = await documentsDB.listDocuments({ + databaseId: '', + collectionId: '', + queries: [ + Query.limit(25), + Query.cursorAfter(lastId) + ] +}); +``` + +```client-flutter +import 'package:appwrite/appwrite.dart'; + +void main() async { + final client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject(''); + + final documentsDB = DocumentsDB(client); + + final page1 = await documentsDB.listDocuments( + databaseId: '', + collectionId: '', + queries: [ + Query.limit(25) + ] + ); + + final lastId = page1.documents[page1.documents.length - 1].$id; + + final page2 = await documentsDB.listDocuments( + databaseId: '', + collectionId: '', + queries: [ + Query.limit(25), + Query.cursorAfter(lastId) + ] + ); +} +``` +```client-apple +import Appwrite +import AppwriteModels + +func main() async throws { + let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + + let documentsDB = DocumentsDB(client) + + let page1 = try await documentsDB.listDocuments( + databaseId: "", + collectionId: "", + queries: [ + Query.limit(25) + ] + ) + + let lastId = page1.documents[page1.documents.count - 1].$id + + let page2 = try await documentsDB.listDocuments( + databaseId: "", + collectionId: "", + queries: [ + Query.limit(25), + Query.cursorAfter(lastId) + ] + ) +} +``` +```client-android-kotlin +import io.appwrite.Client +import io.appwrite.Query +import io.appwrite.services.DocumentsDB + +suspend fun main() { + val client = Client(applicationContext) + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + + val documentsDB = DocumentsDB(client) + + val page1 = documentsDB.listDocuments( + databaseId = "", + collectionId = "", + queries = listOf( + Query.limit(25) + ) + ) + + val lastId = page1.documents[page1.documents.size - 1].$id + + val page2 = documentsDB.listDocuments( + databaseId = "", + collectionId = "", + queries = listOf( + Query.limit(25), + Query.cursorAfter(lastId) + ) + ) +} +``` + +{% /multicode %} + +# When to use what? {% #when-to-use %} +Offset pagination should be used for collections that rarely change. +Offset pagination lets you build an indicator of the current page number and the total page count. +For example, a list with up to 20 pages or static data like a list of countries or currencies. +Using offset pagination on large and frequently updated collections may result in slow performance and **missing and duplicate** results. + +Cursor pagination should be used for frequently updated collections. +It is best suited for lazy-loaded pages with infinite scrolling. +For example, a feed, comment section, chat history, or high volume datasets. + +# Cache list responses {% #cache-list-responses %} + +You can cache list responses by passing a `ttl` (time-to-live) value in seconds. Subsequent identical requests return the cached result until the TTL expires. The cache is permission-aware, so users with different roles never see each other's cached data. + +Set `ttl` between `1` and `86400` (24 hours). The default is `0` (caching disabled). The response includes an `X-Appwrite-Cache` header with value `hit` or `miss`. + +{% multicode %} +```client-web +import { Client, Query, DocumentsDB } from "appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject(''); + +const documentsDB = new DocumentsDB(client); + +const page = await documentsDB.listDocuments({ + databaseId: '', + collectionId: '', + queries: [ + Query.limit(25) + ], + ttl: 60 // Cache for 60 seconds +}); +``` +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const documentsDB = new sdk.DocumentsDB(client); + +const page = await documentsDB.listDocuments({ + databaseId: '', + collectionId: '', + queries: [ + sdk.Query.limit(25) + ], + ttl: 60 // Cache for 60 seconds +}); +``` +```server-python +from appwrite.client import Client +from appwrite.services.documents_db import DocumentsDB +from appwrite.query import Query + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') +client.set_project('') +client.set_key('') + +documents_db = DocumentsDB(client) + +page = documents_db.list_documents( + database_id='', + collection_id='', + queries=[ + Query.limit(25) + ], + ttl=60 # Cache for 60 seconds +) +``` +```server-ruby +require 'appwrite' + +client = Appwrite::Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') + .set_project('') + .set_key('') + +documents_db = Appwrite::DocumentsDB.new(client) + +page = documents_db.list_documents( + database_id: '', + collection_id: '', + queries: [ + Appwrite::Query.limit(25) + ], + ttl: 60 # Cache for 60 seconds +) +``` +```server-deno +import { Client, Query, DocumentsDB } from "https://deno.land/x/appwrite/mod.ts"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const documentsDB = new DocumentsDB(client); + +const page = await documentsDB.listDocuments({ + databaseId: '', + collectionId: '', + queries: [ + Query.limit(25) + ], + ttl: 60 // Cache for 60 seconds +}); +``` +```server-php +setEndpoint('https://.cloud.appwrite.io/v1') + ->setProject('') + ->setKey(''); + +$documentsDB = new DocumentsDB($client); + +$page = $documentsDB->listDocuments( + databaseId: '', + collectionId: '', + queries: [ + Query::limit(25) + ], + ttl: 60 // Cache for 60 seconds +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +void main() async { + final client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + + final documentsDB = DocumentsDB(client); + + final page = await documentsDB.listDocuments( + databaseId: '', + collectionId: '', + queries: [ + Query.limit(25) + ], + ttl: 60 // Cache for 60 seconds + ); +} +``` +```server-swift +import Appwrite +import AppwriteModels + +func main() async throws { + let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + + let documentsDB = DocumentsDB(client) + + let page = try await documentsDB.listDocuments( + databaseId: "", + collectionId: "", + queries: [ + Query.limit(25) + ], + ttl: 60 // Cache for 60 seconds + ) +} +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.Query +import io.appwrite.services.DocumentsDB + +suspend fun main() { + val client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + + val documentsDB = DocumentsDB(client) + + val page = documentsDB.listDocuments( + databaseId = "", + collectionId = "", + queries = listOf( + Query.limit(25) + ), + ttl = 60 // Cache for 60 seconds + ) +} +``` +```server-rust +use appwrite::Client; +use appwrite::services::documents_db::DocumentsDB; +use appwrite::query::Query; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new() + .set_endpoint("https://.cloud.appwrite.io/v1") + .set_project("") + .set_key(""); + + let documents_db = DocumentsDB::new(&client); + + let page = documents_db.list_documents( + "", + "", + Some(vec![ + Query::limit(25).to_string(), + ]), + None, // transaction_id + None, // total + Some(60), // ttl - Cache for 60 seconds + ).await?; + + println!("{:?}", page); + Ok(()) +} +``` +```graphql +query { + documentsDBListDocuments( + databaseId: "", + collectionId: "", + queries: ["limit(25)"], + ttl: 60 + ) { + total + documents { + _id + data + } + } +} +``` +```http +GET /v1/documentsdb//collections//documents?ttl=60 HTTP/1.1 +Content-Type: application/json +X-Appwrite-Project: +``` +{% /multicode %} + +Document writes do **not** invalidate the cache, so cached responses may contain stale data until the TTL expires. Use a short TTL for collections that change often, or skip caching entirely when you always need the latest documents. diff --git a/src/routes/docs/products/databases/documentsdb/permissions/+page.markdoc b/src/routes/docs/products/databases/documentsdb/permissions/+page.markdoc new file mode 100644 index 00000000000..5ccd0905b35 --- /dev/null +++ b/src/routes/docs/products/databases/documentsdb/permissions/+page.markdoc @@ -0,0 +1,35 @@ +--- +layout: article +title: Database permissions +description: Control access to your DocumentsDB data with permissions. Learn how to set collection level and document level access rules. +--- + +Permissions define who can access documents in a collection. By default **no permissions** are granted to any users, so no user can access any documents. +Permissions exist at two levels, collection level and document level permissions. + +In Appwrite, permissions are **granted**, meaning a user has no access by default and receives access when granted. +A user with access granted at either collection level or document level will be able to access a document. +Users **don't need access at both levels** to access documents. + +# Collection level {% #collection-level %} +Collection level permissions apply to every document in the collection. +If a user has read, create, update, or delete permissions at the collection level, the user can access **all documents** inside the collection. + +Configure collection level permissions by navigating to **Your collection** > **Security** > **Permissions**. + +[Learn more about permissions and roles](/docs/advanced/platform/permissions) + +# Document level {% #document-level %} +Document level permissions grant access to individual documents. +If a user has read, create, update, or delete permissions at the document level, the user can access the **individual document**. + +Document level permissions are only applied if row level security is enabled in the security settings of your collection. +Enable document level permissions by navigating to **Your collection** > **Security** > **Row level security (RLS)**. + +Document level permissions are configured on individual documents. + +[Learn more about permissions and roles](/docs/advanced/platform/permissions) + +# Common use cases {% #common-use-cases %} + +For examples of how to implement common permission patterns, including creating private documents that are only accessible to their creators, see the [permissions examples](/docs/advanced/platform/permissions#examples) in our platform documentation. diff --git a/src/routes/docs/products/databases/documentsdb/queries/+page.markdoc b/src/routes/docs/products/databases/documentsdb/queries/+page.markdoc new file mode 100644 index 00000000000..34d9f057694 --- /dev/null +++ b/src/routes/docs/products/databases/documentsdb/queries/+page.markdoc @@ -0,0 +1,1855 @@ +--- +layout: article +title: Queries +description: Harness the power of querying with Appwrite DocumentsDB. Discover various query options, filtering, sorting, and advanced querying techniques. +--- + +Many list endpoints in Appwrite allow you to filter, sort, and paginate results using queries. Appwrite provides a common set of syntax to build queries. + +# Query class {% #query-class %} + +Appwrite SDKs provide a `Query` class to help you build queries. The `Query` class has methods for each type of supported query operation. + +# Building queries {% #building-queries %} + +Queries are passed to an endpoint through the `queries` parameter as an array of query strings, which can be generated using the `Query` class. + +Each query method is logically separated via `AND` operations. For `OR` operation, pass multiple values into the query method separated by commas. +For example `Query.equal('title', ['Avatar', 'Lord of the Rings'])` will fetch the movies `Avatar` or `Lord of the Rings`. + +{% info title="Default pagination behavior" %} +By default, results are limited to the **first 25 items**. +You can change this through [pagination](/docs/products/databases/documentsdb/pagination). +{% /info %} + +{% multicode %} + +```client-web +import { Client, Query, DocumentsDB } from "appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject(''); + +const documentsDB = new DocumentsDB(client); + +documentsDB.listDocuments({ + databaseId: '', + collectionId: '', + queries: [ + Query.equal('title', ['Avatar', 'Lord of the Rings']), + Query.greaterThan('year', 1999) + ] +}); +``` +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client(); + +const documentsDB = new sdk.DocumentsDB(client); + +client + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey('') +; + +const promise = documentsDB.listDocuments({ + databaseId: '', + collectionId: '', + queries: [ + sdk.Query.equal('title', ['Avatar', 'Lord of the Rings']), + sdk.Query.greaterThan('year', 1999) + ] +}); + +promise.then(function (response) { + console.log(response); +}, function (error) { + console.log(error); +}); +``` +```client-flutter +import 'package:appwrite/appwrite.dart'; + +void main() async { + final client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject(''); + + final documentsDB = DocumentsDB(client); + + try { + final documents = await documentsDB.listDocuments( + '', + '', + [ + Query.equal('title', ['Avatar', 'Lord of the Rings']), + Query.greaterThan('year', 1999) + ] + ); + } on AppwriteException catch(e) { + print(e); + } +} +``` +```client-apple +import Appwrite +import AppwriteModels + +func main() async throws { + let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + + let documentsDB = DocumentsDB(client) + + do { + let documents = try await documentsDB.listDocuments( + databaseId: "", + collectionId: "", + queries: [ + Query.equal("title", value: ["Avatar", "Lord of the Rings"]), + Query.greaterThan("year", value: 1999) + ] + ) + } catch { + print(error.localizedDescription) + } +} +``` +```client-android-kotlin +import io.appwrite.Client +import io.appwrite.Query +import io.appwrite.services.DocumentsDB + +suspend fun main() { + val client = Client(applicationContext) + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject(''); + + val documentsDB = DocumentsDB(client) + + try { + val documents = documentsDB.listDocuments( + databaseId = "", + collectionId = "", + queries = listOf( + Query.equal("title", listOf("Avatar", "Lord of the Rings")), + Query.greaterThan("year", 1999) + ) + ) + } catch (e: AppwriteException) { + Log.e("Appwrite", e.message) + } +} +``` +```server-go +package main + +import ( + "fmt" + "log" + + "github.com/appwrite/sdk-for-go/appwrite" + "github.com/appwrite/sdk-for-go/query" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://.cloud.appwrite.io/v1"), + appwrite.WithProject(""), + appwrite.WithKey(""), + ) + + documentsDB := appwrite.NewDocumentsDB(client) + + documents, err := documentsDB.ListDocuments( + "", + "", + documentsDB.WithListDocumentsQueries([]string{ + query.Equal("title", []string{"Avatar", "Lord of the Rings"}), + query.GreaterThan("year", 1999), + }), + ) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("Documents: %+v\n", documents) +} +``` +```server-rust +use appwrite::Client; +use appwrite::services::documents_db::DocumentsDB; +use appwrite::query::Query; +use serde_json::Value; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new() + .set_endpoint("https://.cloud.appwrite.io/v1") + .set_project("") + .set_key(""); + + let documents_db = DocumentsDB::new(&client); + + let documents = documents_db.list_documents( + "", + "", + Some(vec![ + Query::equal("title", Value::Array(vec![ + Value::String("Avatar".to_string()), + Value::String("Lord of the Rings".to_string()), + ])).to_string(), + Query::greater_than("year", 1999).to_string(), + ]), + None, + None, + None, + ).await?; + + println!("{:?}", documents); + Ok(()) +} +``` +```server-php +setEndpoint('https://.cloud.appwrite.io/v1') + ->setProject('') + ->setKey('') +; + +$documentsDB = new DocumentsDB($client); + +$result = $documentsDB->listDocuments( + '', + '', + [ + Query::equal('title', ['Avatar', 'Lord of the Rings']), + Query::greaterThan('year', 1999) + ] +); +``` +```server-python +from appwrite.client import Client +from appwrite.query import Query +from appwrite.services.documents_db import DocumentsDB + +client = Client() + +(client + .set_endpoint('https://.cloud.appwrite.io/v1') + .set_project('') + .set_key('') +) + +documentsDB = DocumentsDB(client) + +result = documentsDB.list_documents( + '', + '', + [ + Query.equal('title', ['Avatar', 'Lord of the Rings']), + Query.greater_than('year', 1999) + ] +) +``` +```graphql +query { + documentsDBListDocuments( + databaseId: "", + collectionId: "" + queries: [ + "{\"method\":\"equal\",\"attribute\":\"title\",\"values\":[\"Avatar\",\"Lord of the Rings\"]}", + "{\"method\":\"greaterThan\",\"attribute\":\"year\",\"values\":[1999]}" + ] + ) { + total + documents { + _id + data + } + } +} +``` +```http +GET /v1/documentsdb//collections//documents?queries[]=%7B%22method%22%3A%22equal%22%2C%22attribute%22%3A%22title%22%2C%22values%22%3A%5B%22Avatar%22%2C%22Lord%20of%20the%20Rings%22%5D%7D&queries[]=%7B%22method%22%3A%22greaterThan%22%2C%22attribute%22%3A%22year%22%2C%22values%22%3A%5B1999%5D%7D HTTP/1.1 +Content-Type: application/json +X-Appwrite-Project: +``` +```bash +appwrite documents-db list-documents \ + --database-id \ + --collection-id \ + --queries '{"method":"equal","attribute":"title","values":["Avatar","Lord of the Rings"]}' '{"method":"greaterThan","attribute":"year","values":[1999]}' +``` +{% /multicode %} + +# Query operators {% #query-operators %} + +## Select {% #select %} + +The `select` operator allows you to specify which fields should be returned from a document. This optimizes response size and retrieves only the data you need. + +{% multicode %} +```client-web +Query.select(["name", "title"]) +``` +```client-flutter +Query.select(["name", "title"]) +``` +```server-python +Query.select(["name", "title"]) +``` +```server-ruby +Query.select(["name", "title"]) +``` +```server-deno +Query.select(["name", "title"]) +``` +```server-php +Query::select(["name", "title"]) +``` +```client-apple +Query.select(["name", "title"]) +``` +```server-go +query.Select([]string{"name", "title"}) +``` +```server-rust +Query::select(vec!["name", "title"]).to_string() +``` +```http +{"method":"select","values":["name","title"]} +``` +{% /multicode %} + +### Use selection patterns {% #select-patterns %} + +| Pattern | Description | Use case | +|---------|-------------|----------| +| `["field1", "field2"]` | Specific fields only | Minimize response size | +| `["*"]` | All document fields | Get complete document data | + +### Optimize performance {% #select-performance %} + +**Optimize response size** - Only select the fields you actually need. Smaller responses are faster to transfer and parse. + +**Reduce database load** - Selecting fewer fields reduces database processing time, especially for large documents. + +## Comparison operators {% #comparison %} + +### Equal {% #equal %} + +Returns document if field is equal to any value in the provided array. + +{% multicode %} +```client-web +Query.equal("title", ["Iron Man"]) +``` +```client-flutter +Query.equal("title", ["Iron Man"]) +``` +```server-python +Query.equal("title", ["Iron Man"]) +``` +```server-ruby +Query.equal("title", ["Iron Man"]) +``` +```server-deno +Query.equal("title", ["Iron Man"]) +``` +```server-php +Query::equal("title", ["Iron Man"]) +``` +```client-apple +Query.equal("title", value: ["Iron Man"]) +``` +```server-go +query.Equal("title", []string{"Iron Man"}) +``` +```server-rust +Query::equal("title", Value::Array(vec![Value::String("Iron Man".to_string())])).to_string() +``` +```http +{"method":"equal","attribute":"title","values":["Iron Man"]} +``` +{% /multicode %} + +### Not equal {% #not-equal %} + +Returns document if field is not equal to any value in the provided array. + +{% multicode %} +```client-web +Query.notEqual("title", "Iron Man") +``` +```client-flutter +Query.notEqual("title", "Iron Man") +``` +```server-python +Query.not_equal("title", "Iron Man") +``` +```server-ruby +Query.not_equal("title", "Iron Man") +``` +```server-deno +Query.notEqual("title", "Iron Man") +``` +```server-php +Query::notEqual("title", "Iron Man") +``` +```client-apple +Query.notEqual("title", value: "Iron Man") +``` +```server-go +query.NotEqual("title", "Iron Man") +``` +```server-rust +Query::not_equal("title", "Iron Man").to_string() +``` +```http +{"method":"notEqual","attribute":"title","values":"Iron Man"} +``` +{% /multicode %} + +### Less than {% #less-than %} + +Returns document if field is less than the provided value. + +{% multicode %} +```client-web +Query.lessThan("score", 10) +``` +```client-flutter +Query.lessThan("score", 10) +``` +```server-python +Query.less_than("score", 10) +``` +```server-ruby +Query.less_than("score", 10) +``` +```server-deno +Query.lessThan("score", 10) +``` +```server-php +Query::lessThan("score", 10) +``` +```client-apple +Query.lessThan("score", value: 10) +``` +```server-go +query.LessThan("score", 10) +``` +```server-rust +Query::less_than("score", 10).to_string() +``` +```http +{"method":"lessThan","attribute":"score","values":[10]} +``` +{% /multicode %} + +### Less than or equal {% #less-than-equal %} + +Returns document if field is less than or equal to the provided value. + +{% multicode %} +```client-web +Query.lessThanEqual("score", 10) +``` +```client-flutter +Query.lessThanEqual("score", 10) +``` +```server-python +Query.less_than_equal("score", 10) +``` +```server-ruby +Query.less_than_equal("score", 10) +``` +```server-deno +Query.lessThanEqual("score", 10) +``` +```server-php +Query::lessThanEqual("score", 10) +``` +```client-apple +Query.lessThanEqual("score", value: 10) +``` +```server-go +query.LessThanEqual("score", 10) +``` +```server-rust +Query::less_than_equal("score", 10).to_string() +``` +```http +{"method":"lessThanEqual","attribute":"score","values":[10]} +``` +{% /multicode %} + +### Greater than {% #greater-than %} + +Returns document if field is greater than the provided value. + +{% multicode %} +```client-web +Query.greaterThan("score", 10) +``` +```client-flutter +Query.greaterThan("score", 10) +``` +```server-python +Query.greater_than("score", 10) +``` +```server-ruby +Query.greater_than("score", 10) +``` +```server-deno +Query.greaterThan("score", 10) +``` +```server-php +Query::greaterThan("score", 10) +``` +```client-apple +Query.greaterThan("score", value: 10) +``` +```server-go +query.GreaterThan("score", 10) +``` +```server-rust +Query::greater_than("score", 10).to_string() +``` +```http +{"method":"greaterThan","attribute":"score","values":[10]} +``` +{% /multicode %} + +### Greater than or equal {% #greater-than-equal %} + +Returns document if field is greater than or equal to the provided value. + +{% multicode %} +```client-web +Query.greaterThanEqual("score", 10) +``` +```client-flutter +Query.greaterThanEqual("score", 10) +``` +```server-python +Query.greater_than_equal("score", 10) +``` +```server-ruby +Query.greater_than_equal("score", 10) +``` +```server-deno +Query.greaterThanEqual("score", 10) +``` +```server-php +Query::greaterThanEqual("score", 10) +``` +```client-apple +Query.greaterThanEqual("score", value: 10) +``` +```server-go +query.GreaterThanEqual("score", 10) +``` +```server-rust +Query::greater_than_equal("score", 10).to_string() +``` +```http +{"method":"greaterThanEqual","attribute":"score","values":[10]} +``` +{% /multicode %} + +### Between {% #between %} + +Returns document if field value falls between the two values. The boundary values are inclusive and can be strings or numbers. + +{% multicode %} +```client-web +Query.between("price", 5, 10) +``` +```client-flutter +Query.between("price", 5, 10) +``` +```server-python +Query.between("price", 5, 10) +``` +```server-ruby +Query.between("price", 5, 10) +``` +```server-deno +Query.between("price", 5, 10) +``` +```server-php +Query::between("price", 5, 10) +``` +```client-apple +Query.between("price", start: 5, end: 10) +``` +```server-go +query.Between("price", 5, 10) +``` +```server-rust +Query::between("price", 5, 10).to_string() +``` +```http +{"method":"between","attribute":"price","values":[5,10]} +``` +{% /multicode %} + +### Not between {% #not-between %} + +Returns documents if the field value is outside the range defined by the two values (strictly less than start OR strictly greater than end). +Works with strings or numbers. Boundary values are excluded. + +{% multicode %} +```client-web +Query.notBetween("price", 5, 10) +``` +```client-flutter +Query.notBetween("price", 5, 10) +``` +```client-apple +Query.notBetween("price", start: 5, end: 10) +``` +```client-android-kotlin +Query.notBetween("price", 5, 10) +``` +```client-android-java +Query.notBetween("price", 5, 10) +``` +```server-python +Query.not_between("price", 5, 10) +``` +```server-ruby +Query.not_between("price", 5, 10) +``` +```server-deno +Query.notBetween("price", 5, 10) +``` +```server-nodejs +Query.notBetween("price", 5, 10) +``` +```server-php +Query::notBetween("price", 5, 10) +``` +```server-swift +Query.notBetween("price", start: 5, end: 10) +``` +```server-rust +Query::not_between("price", 5, 10).to_string() +``` +```http +{"method":"notBetween","attribute":"price","values":[5,10]} +``` +{% /multicode %} + +## Null checks {% #null-checks %} + +### Is null {% #is-null %} + +Returns documents where field value is null. + +{% multicode %} +```client-web +Query.isNull("name") +``` +```client-flutter +Query.isNull("name") +``` +```server-python +Query.is_null("name") +``` +```server-ruby +Query.is_null("name") +``` +```server-deno +Query.isNull("name") +``` +```server-php +Query::isNull("name") +``` +```client-apple +Query.isNull("name") +``` +```server-go +query.IsNull("name") +``` +```server-rust +Query::is_null("name").to_string() +``` +```http +{"method":"isNull","attribute":"name"} +``` +{% /multicode %} + +### Is not null {% #is-not-null %} + +Returns documents where field value is **not** null. + +{% multicode %} +```client-web +Query.isNotNull("name") +``` +```client-flutter +Query.isNotNull("name") +``` +```server-python +Query.is_not_null("name") +``` +```server-ruby +Query.is_not_null("name") +``` +```server-deno +Query.isNotNull("name") +``` +```server-php +Query::isNotNull("name") +``` +```client-apple +Query.isNotNull("name") +``` +```server-go +query.IsNotNull("name") +``` +```server-rust +Query::is_not_null("name").to_string() +``` +```http +{"method":"isNotNull","attribute":"name"} +``` +{% /multicode %} + +## String operations {% #string-operations %} + +### Starts with {% #starts-with %} + +Returns documents if a string field starts with a substring. + +{% multicode %} +```client-web +Query.startsWith("name", "Once upon a time") +``` +```client-flutter +Query.startsWith("name", "Once upon a time") +``` +```server-python +Query.starts_with("name", "Once upon a time") +``` +```server-ruby +Query.starts_with("name", "Once upon a time") +``` +```server-deno +Query.startsWith("name", "Once upon a time") +``` +```server-php +Query::startsWith("name", "Once upon a time") +``` +```client-apple +Query.startsWith("name", value: "Once upon a time") +``` +```server-go +query.StartsWith("name", "Once upon a time") +``` +```server-rust +Query::starts_with("name", "Once upon a time").to_string() +``` +```http +{"method":"startsWith","attribute":"name","values":["Once upon a time"]} +``` +{% /multicode %} + +### Not starts with {% #not-starts-with %} + +Returns documents if a string field does not start with a substring. + +{% multicode %} +```client-web +Query.notStartsWith("name", "Once upon a time") +``` +```client-flutter +Query.notStartsWith("name", "Once upon a time") +``` +```client-apple +Query.notStartsWith("name", value: "Once upon a time") +``` +```client-android-kotlin +Query.notStartsWith("name", "Once upon a time") +``` +```client-android-java +Query.notStartsWith("name", "Once upon a time") +``` +```server-python +Query.not_starts_with("name", "Once upon a time") +``` +```server-ruby +Query.not_starts_with("name", "Once upon a time") +``` +```server-deno +Query.notStartsWith("name", "Once upon a time") +``` +```server-nodejs +Query.notStartsWith("name", "Once upon a time") +``` +```server-php +Query::notStartsWith("name", "Once upon a time") +``` +```server-swift +Query.notStartsWith("name", value: "Once upon a time") +``` +```server-rust +Query::not_starts_with("name", "Once upon a time").to_string() +``` +```http +{"method":"notStartsWith","attribute":"name","values":["Once upon a time"]} +``` +{% /multicode %} + +### Ends with {% #ends-with %} + +Returns documents if a string field ends with a substring. + +{% multicode %} +```client-web +Query.endsWith("name", "happily ever after.") +``` +```client-flutter +Query.endsWith("name", "happily ever after.") +``` +```server-python +Query.ends_with("name", "happily ever after.") +``` +```server-ruby +Query.ends_with("name", "happily ever after.") +``` +```server-deno +Query.endsWith("name", "happily ever after.") +``` +```server-php +Query::endsWith("name", "happily ever after.") +``` +```client-apple +Query.endsWith("name", value: "happily ever after.") +``` +```server-go +query.EndsWith("name", "happily ever after.") +``` +```server-rust +Query::ends_with("name", "happily ever after.").to_string() +``` +```http +{"method":"endsWith","attribute":"name","values":["happily ever after."]} +``` +{% /multicode %} + +### Not ends with {% #not-ends-with %} + +Returns documents if a string field does not end with a substring. + +{% multicode %} +```client-web +Query.notEndsWith("name", "happily ever after.") +``` +```client-flutter +Query.notEndsWith("name", "happily ever after.") +``` +```client-apple +Query.notEndsWith("name", value: "happily ever after.") +``` +```client-android-kotlin +Query.notEndsWith("name", "happily ever after.") +``` +```client-android-java +Query.notEndsWith("name", "happily ever after.") +``` +```server-python +Query.not_ends_with("name", "happily ever after.") +``` +```server-ruby +Query.not_ends_with("name", "happily ever after.") +``` +```server-deno +Query.notEndsWith("name", "happily ever after.") +``` +```server-nodejs +Query.notEndsWith("name", "happily ever after.") +``` +```server-php +Query::notEndsWith("name", "happily ever after.") +``` +```server-swift +Query.notEndsWith("name", value: "happily ever after.") +``` +```server-rust +Query::not_ends_with("name", "happily ever after.").to_string() +``` +```http +{"method":"notEndsWith","attribute":"name","values":["happily ever after."]} +``` +{% /multicode %} + +### Contains {% #contains %} + +Returns documents if the array field contains the specified elements or if a string field contains the specified substring. + +{% multicode %} +```client-web +// For arrays +Query.contains("ingredients", ['apple', 'banana']) + +// For strings +Query.contains("name", "Tom") +``` +```client-flutter +// For arrays +Query.contains("ingredients", ['apple', 'banana']) + +// For strings +Query.contains("name", "Tom") +``` +```server-python +# For arrays +Query.contains("ingredients", ['apple', 'banana']) + +# For strings +Query.contains("name", "Tom") +``` +```server-ruby +# For arrays +Query.contains("ingredients", ['apple', 'banana']) + +# For strings +Query.contains("name", "Tom") +``` +```server-deno +// For arrays +Query.contains("ingredients", ['apple', 'banana']) + +// For strings +Query.contains("name", "Tom") +``` +```server-php +// For arrays +Query::contains("ingredients", ['apple', 'banana']) + +// For strings +Query::contains("name", "Tom") +``` +```client-apple +// For arrays +Query.contains("ingredients", value: ["apple", "banana"]) + +// For strings +Query.contains("name", value: "Tom") +```server-go +// For arrays +query.Contains("ingredients", []string{"apple", "banana"}) + +// For strings +query.Contains("name", "Tom") +``` +```server-rust +// For arrays +Query::contains("ingredients", Value::Array(vec![ + Value::String("apple".to_string()), + Value::String("banana".to_string()), +])).to_string() + +// For strings +Query::contains("name", "Tom").to_string() +``` +```http +# For arrays +{"method":"contains","attribute":"ingredients","values":["apple","banana"]} + +# For strings +{"method":"contains","attribute":"name","values":["Tom"]} +``` +{% /multicode %} + +### Not contains {% #not-contains %} + +Returns documents if the array field does not contain the specified +elements, or if a string field does not contain the specified +substring. + +{% multicode %} +```client-web +// For arrays +Query.notContains("ingredients", ['apple', 'banana']) + +// For strings +Query.notContains("name", "Tom") +``` +```client-flutter +// For arrays +Query.notContains("ingredients", ['apple', 'banana']) + +// For strings +Query.notContains("name", "Tom") +``` +```client-react-native +// For arrays +Query.notContains("ingredients", ['apple', 'banana']) + +// For strings +Query.notContains("name", "Tom") +``` +```client-apple +// For arrays +Query.notContains("ingredients", value: ['apple', 'banana']) + +// For strings +Query.notContains("name", value: "Tom") +``` +```client-android-kotlin +// For arrays +Query.notContains("ingredients", ['apple', 'banana']) + +// For strings +Query.notContains("name", "Tom") +``` +```client-android-java +// For arrays +Query.notContains("ingredients", Arrays.asList("apple", "banana")) + +// For strings +Query.notContains("name", "Tom") +``` +```server-python +# For arrays +Query.not_contains("ingredients", ['apple', 'banana']) + +# For strings +Query.not_contains("name", "Tom") +``` +```server-ruby +# For arrays +Query.not_contains("ingredients", ['apple', 'banana']) + +# For strings +Query.not_contains("name", "Tom") +``` +```server-deno +// For arrays +Query.notContains("ingredients", ['apple', 'banana']) + +// For strings +Query.notContains("name", "Tom") +``` +```server-nodejs +// For arrays +Query.notContains("ingredients", ['apple', 'banana']) + +// For strings +Query.notContains("name", "Tom") +``` +```server-php +// For arrays +Query::notContains("ingredients", ['apple', 'banana']) + +// For strings +Query::notContains("name", "Tom") +``` +```server-dotnet +// For arrays +Query.NotContains("ingredients", new List { "apple", "banana" }) + +// For strings +Query.NotContains("name", "Tom") +``` +```server-go +// For arrays +query.NotContains("ingredients", []string{"apple", "banana"}) + +// For strings +query.NotContains("name", "Tom") +```server-dart +// For arrays +Query.notContains("ingredients", ['apple', 'banana']) + +// For strings +Query.notContains("name", "Tom") +``` +```server-swift +// For arrays +Query.notContains("ingredients", value: ['apple', 'banana']) + +// For strings +Query.notContains("name", value: "Tom") +``` +```server-kotlin +// For arrays +Query.notContains("ingredients", listOf("apple", "banana")) + +// For strings +Query.notContains("name", "Tom") +``` +```server-rust +// For arrays +Query::not_contains("ingredients", Value::Array(vec![ + Value::String("apple".to_string()), + Value::String("banana".to_string()), +])).to_string() + +// For strings +Query::not_contains("name", "Tom").to_string() +``` +```http +# For arrays +{"method":"notContains","attribute":"ingredients","values":["apple","banana"]} + +# For strings +{"method":"notContains","attribute":"name","values":["Tom"]} +``` +{% /multicode %} + +### Search {% #search %} + +Searches string fields for provided keywords. Requires a [full-text index](/docs/products/databases/documentsdb/collections#indexes) on queried fields. + +{% multicode %} +```client-web +Query.search("text", "key words") +``` +```client-flutter +Query.search("text", "key words") +``` +```server-python +Query.search("text", "key words") +``` +```server-ruby +Query.search("text", "key words") +``` +```server-deno +Query.search("text", "key words") +``` +```server-php +Query::search("text", "key words") +``` +```client-apple +Query.search("text", value: "key words") +``` +```server-go +query.Search("text", "key words") +``` +```server-rust +Query::search("text", "key words").to_string() +``` +```http +{"method":"search","attribute":"text","values":["key words"]} +``` +{% /multicode %} + +### Not search {% #not-search %} + +Returns documents if a string field does not match the full-text search +query. Requires a [full-text index](/docs/products/databases/documentsdb/collections#indexes) +on queried fields. + +{% multicode %} +```client-web +Query.notSearch("text", "key words") +``` +```client-flutter +Query.notSearch("text", "key words") +``` +```client-apple +Query.notSearch("text", value: "key words") +``` +```client-android-kotlin +Query.notSearch("text", "key words") +``` +```client-android-java +Query.notSearch("text", "key words") +``` +```server-python +Query.not_search("text", "key words") +``` +```server-ruby +Query.not_search("text", "key words") +``` +```server-deno +Query.notSearch("text", "key words") +``` +```server-nodejs +Query.notSearch("text", "key words") +``` +```server-php +Query::notSearch("text", "key words") +``` +```server-swift +Query.notSearch("text", value: "key words") +``` +```server-rust +Query::not_search("text", "key words").to_string() +``` +```http +{"method":"notSearch","attribute":"text","values":["key words"]} +``` +{% /multicode %} + +## Logical operators {% #logical-operators %} + +### AND {% #and %} + +Returns document if it matches all of the nested sub-queries in the array passed in. + +{% multicode %} +```client-web +Query.and([ + Query.lessThan("size", 10), + Query.greaterThan("size", 5) +]) +``` +```client-flutter +Query.and([ + Query.lessThan("size", 10), + Query.greaterThan("size", 5) +]) +``` +```server-python +Query.and_queries([ + Query.less_than("size", 10), + Query.greater_than("size", 5) +]) +``` +```server-ruby +Query.and([ + Query.less_than("size", 10), + Query.greater_than("size", 5) +]) +``` +```server-deno +Query.and([ + Query.lessThan("size", 10), + Query.greaterThan("size", 5) +]) +``` +```server-php +Query::and([ + Query::lessThan("size", 10), + Query::greaterThan("size", 5) +]) +``` +```client-apple +Query.and([ + Query.lessThan("size", value: 10), + Query.greaterThan("size", value: 5) +]) +``` +```server-go +query.And([]string{ + query.LessThan("size", 10), + query.GreaterThan("size", 5), +}) +``` +```server-rust +Query::and(vec![ + Query::less_than("size", 10).to_string(), + Query::greater_than("size", 5).to_string(), +]).to_string() +``` +```http +{"method":"and","values":[{"method":"lessThan","attribute":"size","values":[10]},{"method":"greaterThan","attribute":"size","values":[5]}]} +``` +{% /multicode %} + +### OR {% #or %} + +Returns document if it matches any of the nested sub-queries in the array passed in. + +{% multicode %} +```client-web +Query.or([ + Query.lessThan("size", 5), + Query.greaterThan("size", 10) +]) +``` +```client-flutter +Query.or([ + Query.lessThan("size", 5), + Query.greaterThan("size", 10) +]) +``` +```server-python +Query.or_queries([ + Query.less_than("size", 5), + Query.greater_than("size", 10) +]) +``` +```server-ruby +Query.or([ + Query.less_than("size", 5), + Query.greater_than("size", 10) +]) +``` +```server-deno +Query.or([ + Query.lessThan("size", 5), + Query.greaterThan("size", 10) +]) +``` +```server-php +Query::or([ + Query::lessThan("size", 5), + Query::greaterThan("size", 10) +]) +``` +```client-apple +Query.or([ + Query.lessThan("size", value: 5), + Query.greaterThan("size", value: 10) +]) +``` +```server-go +query.Or([]string{ + query.LessThan("size", 5), + query.GreaterThan("size", 10), +}) +``` +```server-rust +Query::or(vec![ + Query::less_than("size", 5).to_string(), + Query::greater_than("size", 10).to_string(), +]).to_string() +``` +```http +{"method":"or","values":[{"method":"lessThan","attribute":"size","values":[5]},{"method":"greaterThan","attribute":"size","values":[10]}]} +``` +{% /multicode %} + +## Ordering {% #ordering %} + +### Order descending {% #order-desc %} + +Orders results in descending order by field. + +{% multicode %} +```client-web +Query.orderDesc("field") +``` +```client-flutter +Query.orderDesc("field") +``` +```server-python +Query.order_desc("field") +``` +```server-ruby +Query.order_desc("field") +``` +```server-nodejs +Query.orderDesc("field") +``` +```server-php +Query::orderDesc("field") +``` +```client-apple +Query.orderDesc("field") +``` +```server-go +query.OrderDesc("attribute") +``` +```server-rust +Query::order_desc("field").to_string() +``` +```http +{"method":"orderDesc","attribute":"field"} +``` +{% /multicode %} + +### Order ascending {% #order-asc %} + +Orders results in ascending order by field. + +{% multicode %} +```client-web +Query.orderAsc("field") +``` +```client-flutter +Query.orderAsc("field") +``` +```server-python +Query.order_asc("field") +``` +```server-ruby +Query.order_asc("field") +``` +```server-nodejs +Query.orderAsc("field") +``` +```server-php +Query::orderAsc("field") +``` +```client-apple +Query.orderAsc("field") +``` +```server-go +query.OrderAsc("attribute") +``` +```server-rust +Query::order_asc("field").to_string() +``` +```http +{"method":"orderAsc","attribute":"field"} +``` +{% /multicode %} + +## Pagination {% #pagination %} + +### Limit {% #limit %} + +Limits the number of results returned by the query. Used for [pagination](/docs/products/databases/documentsdb/pagination). + +{% multicode %} +```client-web +Query.limit(25) +``` +```client-flutter +Query.limit(25) +``` +```server-python +Query.limit(25) +``` +```server-ruby +Query.limit(25) +``` +```server-deno +Query.limit(25) +``` +```server-php +Query::limit(25) +``` +```client-apple +Query.limit(25) +``` +```server-go +query.Limit(25) +``` +```server-rust +Query::limit(25).to_string() +``` +```http +{"method":"limit","values":[25]} +``` +{% /multicode %} + +### Offset {% #offset %} + +Offset the results returned by skipping some of the results. Used for [pagination](/docs/products/databases/documentsdb/pagination). + +{% multicode %} +```client-web +Query.offset(0) +``` +```client-flutter +Query.offset(0) +``` +```server-python +Query.offset(0) +``` +```server-ruby +Query.offset(0) +``` +```server-deno +Query.offset(0) +``` +```server-php +Query::offset(0) +``` +```client-apple +Query.offset(0) +``` +```server-go +query.Offset(0) +``` +```server-rust +Query::offset(0).to_string() +``` +```http +{"method":"offset","values":[0]} +``` +{% /multicode %} + +### Cursor after {% #cursor-after %} + +Places the cursor after the specified resource ID. Used for [pagination](/docs/products/databases/documentsdb/pagination). + +{% multicode %} +```client-web +Query.cursorAfter("62a7...f620") +``` +```client-flutter +Query.cursorAfter("62a7...f620") +``` +```server-python +Query.cursor_after("62a7...f620") +``` +```server-ruby +Query.cursor_after("62a7...f620") +``` +```server-deno +Query.cursorAfter("62a7...f620") +``` +```server-php +Query::cursorAfter("62a7...f620") +``` +```client-apple +Query.cursorAfter("62a7...f620") +``` +```server-go +query.CursorAfter("62a7...f620") +``` +```server-rust +Query::cursor_after("62a7...f620").to_string() +``` +```http +{"method":"cursorAfter","values":["62a7...f620"]} +``` +{% /multicode %} + +### Cursor before {% #cursor-before %} + +Places the cursor before the specified resource ID. Used for [pagination](/docs/products/databases/documentsdb/pagination). + +{% multicode %} +```client-web +Query.cursorBefore("62a7...a600") +``` +```client-flutter +Query.cursorBefore("62a7...a600") +``` +```server-python +Query.cursor_before("62a7...a600") +``` +```server-ruby +Query.cursor_before("62a7...a600") +``` +```server-deno +Query.cursorBefore("62a7...a600") +``` +```server-php +Query::cursorBefore("62a7...a600") +``` +```client-apple +Query.cursorBefore("62a7...a600") +``` +```server-go +query.CursorBefore("62a7...a600") +``` +```server-rust +Query::cursor_before("62a7...a600").to_string() +``` +```http +{"method":"cursorBefore","values":["62a7...a600"]} +``` +{% /multicode %} + +# Time helpers {% #time-helpers %} + +Built-in helpers for filtering by creation and update timestamps using +ISO 8601 date-time strings (for example, "2025-01-01T00:00:00Z"). + +### Created before {% #created-before %} + +Returns documents created before the given date. + +{% multicode %} +```client-web +Query.createdBefore("2025-01-01T00:00:00Z") +``` +```client-flutter +Query.createdBefore("2025-01-01T00:00:00Z") +``` +```client-apple +Query.createdBefore("2025-01-01T00:00:00Z") +``` +```client-android-kotlin +Query.createdBefore("2025-01-01T00:00:00Z") +``` +```client-android-java +Query.createdBefore("2025-01-01T00:00:00Z") +``` +```server-python +Query.created_before("2025-01-01T00:00:00Z") +``` +```server-ruby +Query.created_before("2025-01-01T00:00:00Z") +``` +```server-deno +Query.createdBefore("2025-01-01T00:00:00Z") +``` +```server-nodejs +Query.createdBefore("2025-01-01T00:00:00Z") +``` +```server-php +Query::createdBefore("2025-01-01T00:00:00Z") +``` +```server-swift +Query.createdBefore("2025-01-01T00:00:00Z") +``` +```server-rust +Query::created_before("2025-01-01T00:00:00Z").to_string() +``` +```http +{"method":"createdBefore","values":["2025-01-01T00:00:00Z"]} +``` +{% /multicode %} + +### Created after {% #created-after %} + +Returns documents created after the given date. + +{% multicode %} +```client-web +Query.createdAfter("2025-01-01T00:00:00Z") +``` +```client-flutter +Query.createdAfter("2025-01-01T00:00:00Z") +``` +```client-apple +Query.createdAfter("2025-01-01T00:00:00Z") +``` +```client-android-kotlin +Query.createdAfter("2025-01-01T00:00:00Z") +``` +```client-android-java +Query.createdAfter("2025-01-01T00:00:00Z") +``` +```server-python +Query.created_after("2025-01-01T00:00:00Z") +``` +```server-ruby +Query.created_after("2025-01-01T00:00:00Z") +``` +```server-deno +Query.createdAfter("2025-01-01T00:00:00Z") +``` +```server-nodejs +Query.createdAfter("2025-01-01T00:00:00Z") +``` +```server-php +Query::createdAfter("2025-01-01T00:00:00Z") +``` +```server-swift +Query.createdAfter("2025-01-01T00:00:00Z") +``` +```server-rust +Query::created_after("2025-01-01T00:00:00Z").to_string() +``` +```http +{"method":"createdAfter","values":["2025-01-01T00:00:00Z"]} +``` +{% /multicode %} + +### Updated before {% #updated-before %} + +Returns documents updated before the given date. + +{% multicode %} +```client-web +Query.updatedBefore("2025-01-01T00:00:00Z") +``` +```client-flutter +Query.updatedBefore("2025-01-01T00:00:00Z") +``` +```client-apple +Query.updatedBefore("2025-01-01T00:00:00Z") +``` +```client-android-kotlin +Query.updatedBefore("2025-01-01T00:00:00Z") +``` +```client-android-java +Query.updatedBefore("2025-01-01T00:00:00Z") +``` +```server-python +Query.updated_before("2025-01-01T00:00:00Z") +``` +```server-ruby +Query.updated_before("2025-01-01T00:00:00Z") +``` +```server-deno +Query.updatedBefore("2025-01-01T00:00:00Z") +``` +```server-nodejs +Query.updatedBefore("2025-01-01T00:00:00Z") +``` +```server-php +Query::updatedBefore("2025-01-01T00:00:00Z") +``` +```server-swift +Query.updatedBefore("2025-01-01T00:00:00Z") +``` +```server-rust +Query::updated_before("2025-01-01T00:00:00Z").to_string() +``` +```http +{"method":"updatedBefore","values":["2025-01-01T00:00:00Z"]} +``` +{% /multicode %} + +### Updated after {% #updated-after %} + +Returns documents updated after the given date. + +{% multicode %} +```client-web +Query.updatedAfter("2025-01-01T00:00:00Z") +``` +```client-flutter +Query.updatedAfter("2025-01-01T00:00:00Z") +``` +```client-apple +Query.updatedAfter("2025-01-01T00:00:00Z") +``` +```client-android-kotlin +Query.updatedAfter("2025-01-01T00:00:00Z") +``` +```client-android-java +Query.updatedAfter("2025-01-01T00:00:00Z") +``` +```server-python +Query.updated_after("2025-01-01T00:00:00Z") +``` +```server-ruby +Query.updated_after("2025-01-01T00:00:00Z") +``` +```server-deno +Query.updatedAfter("2025-01-01T00:00:00Z") +``` +```server-nodejs +Query.updatedAfter("2025-01-01T00:00:00Z") +``` +```server-php +Query::updatedAfter("2025-01-01T00:00:00Z") +``` +```server-swift +Query.updatedAfter("2025-01-01T00:00:00Z") +``` +```server-rust +Query::updated_after("2025-01-01T00:00:00Z").to_string() +``` +```http +{"method":"updatedAfter","values":["2025-01-01T00:00:00Z"]} +``` +{% /multicode %} +# Complex queries {% #complex-queries %} + +You can create complex queries by combining AND and OR operations. For example, to find items that are either books under $20 or magazines under $10: + +{% multicode %} +```client-web +const results = await documentsDB.listDocuments({ + databaseId: '', + collectionId: '', + queries: [ + Query.or([ + Query.and([ + Query.equal('category', ['books']), + Query.lessThan('price', 20) + ]), + Query.and([ + Query.equal('category', ['magazines']), + Query.lessThan('price', 10) + ]) + ]) + ] +}); +``` +```client-flutter +final results = await documentsDB.listDocuments( + '', + '', + [ + Query.or([ + Query.and([ + Query.equal('category', ['books']), + Query.lessThan('price', 20) + ]), + Query.and([ + Query.equal('category', ['magazines']), + Query.lessThan('price', 10) + ]) + ]) + ] +); +``` +```server-python +results = documentsDB.list_documents( + database_id='', + collection_id='', + queries=[ + Query.or_queries([ + Query.and_queries([ + Query.equal('category', ['books']), + Query.less_than('price', 20) + ]), + Query.and_queries([ + Query.equal('category', ['magazines']), + Query.less_than('price', 10) + ]) + ]) + ] +) +``` +```server-go +documents, err := documentsDB.ListDocuments( + "", + "", + documentsDB.WithListDocumentsQueries([]string{ + query.Or([]string{ + query.And([]string{ + query.Equal("category", []string{"books"}), + query.LessThan("price", 20), + }), + query.And([]string{ + query.Equal("category", []string{"magazines"}), + query.LessThan("price", 10), + }), + }), + }), +) +if err != nil { + log.Fatal(err) +} +``` +```server-rust +let documents = documents_db.list_documents( + "", + "", + Some(vec![ + Query::or(vec![ + Query::and(vec![ + Query::equal("category", Value::Array(vec![Value::String("books".to_string())])).to_string(), + Query::less_than("price", 20).to_string(), + ]).to_string(), + Query::and(vec![ + Query::equal("category", Value::Array(vec![Value::String("magazines".to_string())])).to_string(), + Query::less_than("price", 10).to_string(), + ]).to_string(), + ]).to_string(), + ]), + None, + None, + None, +).await?; +``` +```http +{"method":"or","values":[{"method":"and","values":[{"method":"equal","attribute":"category","values":["books"]},{"method":"lessThan","attribute":"price","values":[20]}]},{"method":"and","values":[{"method":"equal","attribute":"category","values":["magazines"]},{"method":"lessThan","attribute":"price","values":[10]}]}]} +``` +{% /multicode %} + +This example demonstrates how to combine `OR` and `AND` operations. The query uses `Query.or()` to match either condition: books under $20 OR magazines under $10. +Each condition within the OR is composed of two AND conditions - one for the category and one for the price threshold. The database will return documents that match either of these combined conditions. + diff --git a/src/routes/docs/products/databases/documentsdb/quick-start/+page.markdoc b/src/routes/docs/products/databases/documentsdb/quick-start/+page.markdoc new file mode 100644 index 00000000000..92c5f30cf8b --- /dev/null +++ b/src/routes/docs/products/databases/documentsdb/quick-start/+page.markdoc @@ -0,0 +1,243 @@ +--- +layout: article +title: Start with DocumentsDB +description: Get started with Appwrite DocumentsDB. Follow a step-by-step guide to create your first database, add a collection, and perform basic document operations. +--- + + +{% section #create-database step=1 title="Create database" %} +Head to your [Appwrite Console](https://cloud.appwrite.io/console/) and click **Create database**. Name it `Oscar` and choose **DocumentsDB** as the database type. +Optionally, add a custom database ID. Select your preferred tier, then click **Create database**. +{% /section %} + +{% section #create-collection step=2 title="Create collection" %} +In the `Oscar` database, click **Create collection** and name it `My books`. Optionally, add a custom collection ID. + +Collections are schemaless, so there are no columns to define. Each document holds its own fields as flexible JSON. + +Open the collection's **Security** tab. Under **Permissions**, add a new role **Any** and check **Create** and **Read**, so anyone can create and read documents. Click **Update** to save. +{% /section %} + + +{% section #create-documents step=3 title="Create documents" %} +To create a document use the `createDocument` method. + +In the **Settings** menu, find your project ID and replace `` in the example. + +Navigate to the `Oscar` database, copy the database ID, and replace ``. +Then, in the `My books` collection, copy the collection ID, and replace ``. + +{% multicode %} +```client-web +import { Client, ID, DocumentsDB } from "appwrite"; + +const client = new Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject(''); + +const documentsDB = new DocumentsDB(client); + +const promise = documentsDB.createDocument({ + databaseId: '', + collectionId: '', + documentId: ID.unique(), + data: { title: "Hamlet" } +}); + +promise.then(function (response) { + console.log(response); +}, function (error) { + console.log(error); +}); +``` +```client-flutter +import 'package:appwrite/appwrite.dart'; + +void main() async { + final client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject(''); + + final documentsDB = DocumentsDB(client); + + try { + final document = documentsDB.createDocument( + databaseId: '', + collectionId: '', + documentId: ID.unique(), + data: { "title": "Hamlet" } + ); + } on AppwriteException catch(e) { + print(e); + } +} +``` +```client-apple +import Appwrite +import AppwriteModels + +func main() async throws { + let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + + let documentsDB = DocumentsDB(client) + + do { + let document = try await documentsDB.createDocument( + databaseId: "", + collectionId: "", + documentId: ID.unique(), + data: ["title": "Hamlet"] + ) + } catch { + print(error.localizedDescription) + } +} +``` +```client-android-kotlin +import io.appwrite.Client +import io.appwrite.ID +import io.appwrite.services.DocumentsDB + +suspend fun main() { + val client = Client(applicationContext) + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + + val documentsDB = DocumentsDB(client) + + try { + val document = documentsDB.createDocument( + databaseId = "", + collectionId = "", + documentId = ID.unique(), + data = mapOf("title" to "Hamlet"), + ) + } catch (e: Exception) { + Log.e("Appwrite", "Error: " + e.message) + } +} +``` +{% /multicode %} + +The response should look similar to this. + +```json +{ + "title": "Hamlet", + "$id": "6a423aa70000c39da0be", + "$sequence": "019f12b5-1c89-7094-8d12-5b7e7a09f025", + "$permissions": [], + "$createdAt": "2026-06-29T09:28:07.047+00:00", + "$updatedAt": "2026-06-29T09:28:07.047+00:00", + "$databaseId": "650125c64b3c25ce4bc4", + "$collectionId": "650125cff227cf9f95ad" +} +``` + +{% /section %} + +{% section #list-documents step=4 title="List documents" %} +To read and query data from your collection, use the `listDocuments` endpoint. + +Like the previous step, replace ``, ``, and `` with their respective IDs. +{% multicode %} +```client-web +import { Client, Query, DocumentsDB } from "appwrite"; + +const client = new Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + +const documentsDB = new DocumentsDB(client); + +const promise = documentsDB.listDocuments({ + databaseId: "", + collectionId: "", + queries: [ + Query.equal('title', 'Hamlet') + ] +}); + +promise.then(function (response) { + console.log(response); +}, function (error) { + console.log(error); +}); +``` +```client-flutter +import 'package:appwrite/appwrite.dart'; + +void main() async { + final client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + + final documentsDB = DocumentsDB(client); + + try { + final documents = await documentsDB.listDocuments( + databaseId: '', + collectionId: '', + queries: [ + Query.equal('title', 'Hamlet') + ] + ); + } on AppwriteException catch(e) { + print(e); + } +} +``` +```client-apple +import Appwrite +import AppwriteModels + +func main() async throws{ + let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + + let documentsDB = DocumentsDB(client) + + do { + let documents = try await documentsDB.listDocuments( + databaseId: "", + collectionId: "", + queries: [ + Query.equal("title", value: "Hamlet") + ] + ) + } catch { + print(error.localizedDescription) + } +} +``` +```client-android-kotlin +import io.appwrite.Client +import io.appwrite.Query +import io.appwrite.services.DocumentsDB + +suspend fun main() { + val client = Client(applicationContext) + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + + val documentsDB = DocumentsDB(client) + + try { + val documents = documentsDB.listDocuments( + databaseId = "", + collectionId = "", + queries = listOf( + Query.equal("title", "Hamlet") + ) + ) + } catch (e: AppwriteException) { + Log.e("Appwrite", "Error: " + e.message) + } +} +``` + +{% /multicode %} +{% /section %} diff --git a/src/routes/docs/products/databases/documentsdb/timestamp-overrides/+page.markdoc b/src/routes/docs/products/databases/documentsdb/timestamp-overrides/+page.markdoc new file mode 100644 index 00000000000..0549b732ab4 --- /dev/null +++ b/src/routes/docs/products/databases/documentsdb/timestamp-overrides/+page.markdoc @@ -0,0 +1,1266 @@ +--- +layout: article +title: Timestamp overrides +description: Set custom $createdAt and $updatedAt timestamps for your documents when using server SDKs. +--- + +When creating or updating documents, Appwrite automatically sets `$createdAt` and `$updatedAt` timestamps. However, there are scenarios where you might need to set these timestamps manually, such as when migrating data from another system or backfilling historical records. + +{% info title="Server SDKs required" %} +To manually set `$createdAt` and `$updatedAt`, you must use a **server SDK** with an **API key**. These attributes can be passed inside the `data` parameter on any of the create, update, or upsert routes (single or bulk). +{% /info %} + +# Setting custom timestamps {% #setting-custom-timestamps %} + +You can override a document's timestamps by providing ISO 8601 strings (for example, `2025-08-10T12:34:56.000Z`) in the `data` payload. If these attributes are not provided, Appwrite will set them automatically. + +Custom timestamps work with all document operations: create, update, upsert, and their bulk variants. + +## Single document operations {% #single-document-operations %} + +When working with individual documents, you can set custom timestamps during create, update, and upsert operations. + +### Create with custom timestamps {% #create-custom %} + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +const documentsDB = new sdk.DocumentsDB(client); + +await documentsDB.createDocument({ + databaseId: '', + collectionId: '', + documentId: sdk.ID.unique(), + data: { + '$createdAt': new Date('2025-08-10T12:34:56.000Z').toISOString(), + '$updatedAt': new Date('2025-08-10T12:34:56.000Z').toISOString(), + // ...your attributes + } +}); +``` +```server-php +use Appwrite\Client; +use Appwrite\ID; +use Appwrite\Services\DocumentsDB; + +$client = (new Client()) + ->setEndpoint('https://.cloud.appwrite.io/v1') + ->setProject('') + ->setKey(''); + +$documentsDB = new DocumentsDB($client); + +$documentsDB->createDocument( + databaseId: '', + collectionId: '', + documentId: ID::unique(), + data: [ + '$createdAt' => (new DateTime(''))->format(DATE_ATOM), + '$updatedAt' => (new DateTime(''))->format(DATE_ATOM), + // ...your attributes + ] +); +``` +```server-swift +import Appwrite +import Foundation + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +let documentsDB = DocumentsDB(client) + +let isoFormatter = ISO8601DateFormatter() +isoFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds] +let customDate = isoFormatter.date(from: "") ?? Date() +let createdAt = isoFormatter.string(from: customDate) +let updatedAt = isoFormatter.string(from: customDate) + +do { + let created = try await documentsDB.createDocument( + databaseId: "", + collectionId: "", + documentId: "", + data: [ + "$createdAt": createdAt, + "$updatedAt": updatedAt, + // ...your attributes + ] + ) + print("Created:", created) +} catch { + print("Create error:", error) +} +``` +```server-python +from appwrite.client import Client +from appwrite.services.documents_db import DocumentsDB +from appwrite.id import ID +from datetime import datetime, timezone + +client = Client() +client.set_endpoint('https://.cloud.appwrite.io/v1') +client.set_project('') +client.set_key('') + +documents_db = DocumentsDB(client) + +iso = datetime(2025, 8, 10, 12, 34, 56, tzinfo=timezone.utc).isoformat() + +documents_db.create_document( + database_id='', + collection_id='', + document_id=ID.unique(), + data={ + '$createdAt': iso, + '$updatedAt': iso, + # ...your attributes + } +) +``` +```server-ruby +require 'appwrite' +require 'time' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') + .set_project('') + .set_key('') + +documents_db = DocumentsDB.new(client) + +custom_date = Time.parse('2025-08-10T12:34:56.000Z').iso8601 + +documents_db.create_document( + database_id: '', + collection_id: '', + document_id: ID.unique(), + data: { + '$createdAt' => custom_date, + '$updatedAt' => custom_date, + # ...your attributes + } +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndpoint("https://.cloud.appwrite.io/v1") + .SetProject("") + .SetKey(""); + +DocumentsDB documentsDB = new DocumentsDB(client); + +string customDate = DateTimeOffset.Parse("2025-08-10T12:34:56.000Z").ToString("O"); + +await documentsDB.CreateDocument( + databaseId: "", + collectionId: "", + documentId: ID.Unique(), + data: new Dictionary + { + ["$createdAt"] = customDate, + ["$updatedAt"] = customDate, + // ...your attributes + } +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +DocumentsDB documentsDB = DocumentsDB(client); + +String customDate = DateTime.parse('2025-08-10T12:34:56.000Z').toIso8601String(); + +await documentsDB.createDocument( + databaseId: '', + collectionId: '', + documentId: ID.unique(), + data: { + '\$createdAt': customDate, + '\$updatedAt': customDate, + // ...your attributes + }, +); +``` +```rust +use appwrite::Client; +use appwrite::services::documents_db::DocumentsDB; +use appwrite::id::ID; +use serde_json::json; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new() + .set_endpoint("https://.cloud.appwrite.io/v1") + .set_project("") + .set_key(""); + + let documents_db = DocumentsDB::new(&client); + + let result = documents_db.create_document( + "", + "", + &ID::unique(), + json!({ + "$createdAt": "2025-08-10T12:34:56.000Z", + "$updatedAt": "2025-08-10T12:34:56.000Z" + // ...your attributes + }), + None, + None, + ).await?; + + println!("Created: {:?}", result); + Ok(()) +} +``` +{% /multicode %} + +### Update with custom timestamps {% #update-custom %} + +When updating documents, you can also set a custom `$updatedAt` timestamp: + +{% multicode %} +```server-nodejs +await documentsDB.updateDocument({ + databaseId: '', + collectionId: '', + documentId: '', + data: { + '$updatedAt': new Date('2025-08-10T12:34:56.000Z').toISOString(), + // ...your attributes + } +}); +``` +```server-php +$documentsDB->updateDocument( + databaseId: '', + collectionId: '', + documentId: '', + data: [ + '$updatedAt' => (new DateTime(''))->format(DATE_ATOM), + // ...your attributes + ] +); +``` +```server-python +from datetime import datetime, timezone + +documents_db.update_document( + database_id='', + collection_id='', + document_id='', + data={ + '$updatedAt': datetime(2025, 8, 10, 12, 34, 56, tzinfo=timezone.utc).isoformat(), + # ...your attributes + } +) +``` +```server-swift +import Appwrite +import Foundation + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +let documentsDB = DocumentsDB(client) + +let isoFormatter = ISO8601DateFormatter() +isoFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds] +let updatedAt = isoFormatter.string(from: isoFormatter.date(from: "") ?? Date()) + +do { + let updated = try await documentsDB.updateDocument( + databaseId: "", + collectionId: "", + documentId: "", + data: [ + "$updatedAt": updatedAt, + // ...your attributes + ] + ) + print("Updated:", updated) +} catch { + print("Update error:", error) +} +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') + .set_project('') + .set_key('') + +documents_db = DocumentsDB.new(client) + +custom_date = Time.parse('').iso8601 + +documents_db.update_document( + database_id: '', + collection_id: '', + document_id: '', + data: { + '$updatedAt' => custom_date, + # ...your attributes + } +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndpoint("https://.cloud.appwrite.io/v1") + .SetProject("") + .SetKey(""); + +DocumentsDB documentsDB = new DocumentsDB(client); + +string customDate = DateTimeOffset.Parse("").ToString("O"); + +await documentsDB.UpdateDocument( + databaseId: "", + collectionId: "", + documentId: "", + data: new Dictionary + { + ["$updatedAt"] = customDate, + // ...your attributes + } +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +DocumentsDB documentsDB = DocumentsDB(client); + +String customDate = DateTime.parse('').toIso8601String(); + +await documentsDB.updateDocument( + databaseId: '', + collectionId: '', + documentId: '', + data: { + '\$updatedAt': customDate, + // ...your attributes + }, +); +``` +```rust +use appwrite::Client; +use appwrite::services::documents_db::DocumentsDB; +use serde_json::json; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new() + .set_endpoint("https://.cloud.appwrite.io/v1") + .set_project("") + .set_key(""); + + let documents_db = DocumentsDB::new(&client); + + let result = documents_db.update_document( + "", + "", + "", + Some(json!({ + "$updatedAt": "2025-08-10T12:34:56.000Z" + // ...your attributes + })), + None, + None, + ).await?; + + println!("Updated: {:?}", result); + Ok(()) +} +``` +{% /multicode %} + +## Bulk operations {% #bulk-operations %} + +Custom timestamps also work with bulk operations, allowing you to set different timestamps for each document in the batch: + +### Bulk create {% #bulk-create %} + +{% multicode %} +```server-nodejs +await documentsDB.createDocuments({ + databaseId: '', + collectionId: '', + documents: [ + { + '$id': sdk.ID.unique(), + '$createdAt': new Date('2024-01-01T00:00:00.000Z').toISOString(), + '$updatedAt': new Date('2024-01-01T00:00:00.000Z').toISOString(), + // ...your attributes + }, + { + '$id': sdk.ID.unique(), + '$createdAt': new Date('2024-02-01T00:00:00.000Z').toISOString(), + '$updatedAt': new Date('2024-02-01T00:00:00.000Z').toISOString(), + // ...your attributes + } + ] +}); +``` +```server-python +documents_db.create_documents( + database_id='', + collection_id='', + documents=[ + { + '$id': ID.unique(), + '$createdAt': datetime(2024, 1, 1, tzinfo=timezone.utc).isoformat(), + '$updatedAt': datetime(2024, 1, 1, tzinfo=timezone.utc).isoformat(), + # ...your attributes + }, + { + '$id': ID.unique(), + '$createdAt': datetime(2024, 2, 1, tzinfo=timezone.utc).isoformat(), + '$updatedAt': datetime(2024, 2, 1, tzinfo=timezone.utc).isoformat(), + # ...your attributes + } + ] +) +``` +```server-php +use Appwrite\Client; +use Appwrite\ID; +use Appwrite\Services\DocumentsDB; + +$client = (new Client()) + ->setEndpoint('https://.cloud.appwrite.io/v1') + ->setProject('') + ->setKey(''); + +$documentsDB = new DocumentsDB($client); + +$documentsDB->createDocuments( + databaseId: '', + collectionId: '', + documents: [ + [ + '$id' => ID::unique(), + '$createdAt' => (new DateTime(''))->format(DATE_ATOM), + '$updatedAt' => (new DateTime(''))->format(DATE_ATOM), + // ...your attributes + ], + [ + '$id' => ID::unique(), + '$createdAt' => (new DateTime(''))->format(DATE_ATOM), + '$updatedAt' => (new DateTime(''))->format(DATE_ATOM), + // ...your attributes + ], + ] +); +``` +```server-swift +import Appwrite +import Foundation + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +let documentsDB = DocumentsDB(client) + +let isoFormatter = ISO8601DateFormatter() +isoFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds] + +let first = isoFormatter.string(from: isoFormatter.date(from: "") ?? Date()) +let second = isoFormatter.string(from: isoFormatter.date(from: "") ?? Date()) + +do { + let bulkCreated = try await documentsDB.createDocuments( + databaseId: "", + collectionId: "", + documents: [ + [ + "$id": ID.unique(), + "$createdAt": first, + "$updatedAt": first, + // ...your attributes + ], + [ + "$id": ID.unique(), + "$createdAt": second, + "$updatedAt": second, + // ...your attributes + ] + ] + ) + print("Bulk create:", bulkCreated) +} catch { + print("Bulk create error:", error) +} +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') + .set_project('') + .set_key('') + +documents_db = DocumentsDB.new(client) + +first = Time.parse('').iso8601 +second = Time.parse('').iso8601 + +documents_db.create_documents( + database_id: '', + collection_id: '', + documents: [ + { + '$id' => ID.unique(), + '$createdAt' => first, + '$updatedAt' => first, + # ...your attributes + }, + { + '$id' => ID.unique(), + '$createdAt' => second, + '$updatedAt' => second, + # ...your attributes + } + ] +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndpoint("https://.cloud.appwrite.io/v1") + .SetProject("") + .SetKey(""); + +DocumentsDB documentsDB = new DocumentsDB(client); + +string first = DateTimeOffset.Parse("").ToString("O"); +string second = DateTimeOffset.Parse("").ToString("O"); + +await documentsDB.CreateDocuments( + databaseId: "", + collectionId: "", + documents: new List + { + new Dictionary + { + ["$id"] = ID.Unique(), + ["$createdAt"] = first, + ["$updatedAt"] = first, + // ...your attributes + }, + new Dictionary + { + ["$id"] = ID.Unique(), + ["$createdAt"] = second, + ["$updatedAt"] = second, + // ...your attributes + } + } +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +DocumentsDB documentsDB = DocumentsDB(client); + +String first = DateTime.parse('').toIso8601String(); +String second = DateTime.parse('').toIso8601String(); + +await documentsDB.createDocuments( + databaseId: '', + collectionId: '', + documents: [ + { + '\$id': ID.unique(), + '\$createdAt': first, + '\$updatedAt': first, + // ...your attributes + }, + { + '\$id': ID.unique(), + '\$createdAt': second, + '\$updatedAt': second, + // ...your attributes + } + ], +); +``` +```rust +use appwrite::Client; +use appwrite::services::documents_db::DocumentsDB; +use appwrite::id::ID; +use serde_json::json; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new() + .set_endpoint("https://.cloud.appwrite.io/v1") + .set_project("") + .set_key(""); + + let documents_db = DocumentsDB::new(&client); + + let result = documents_db.create_documents( + "", + "", + vec![ + json!({ + "$id": ID::unique(), + "$createdAt": "2024-01-01T00:00:00.000Z", + "$updatedAt": "2024-01-01T00:00:00.000Z" + // ...your attributes + }), + json!({ + "$id": ID::unique(), + "$createdAt": "2024-02-01T00:00:00.000Z", + "$updatedAt": "2024-02-01T00:00:00.000Z" + // ...your attributes + }), + ], + None, + ).await?; + + println!("Bulk create: {:?}", result); + Ok(()) +} +``` +{% /multicode %} + +### Bulk upsert {% #bulk-upsert %} + +{% multicode %} +```server-nodejs +await documentsDB.upsertDocuments({ + databaseId: '', + collectionId: '', + documents: [ + { + '$id': '', + '$createdAt': new Date('2024-01-01T00:00:00.000Z').toISOString(), + '$updatedAt': new Date('2025-01-01T00:00:00.000Z').toISOString(), + // ...your attributes + } + ] +}); +``` +```server-python +documents_db.upsert_documents( + database_id='', + collection_id='', + documents=[ + { + '$id': '', + '$createdAt': datetime(2024, 1, 1, tzinfo=timezone.utc).isoformat(), + '$updatedAt': datetime(2025, 1, 1, tzinfo=timezone.utc).isoformat(), + # ...your attributes + } + ] +) +``` +```server-php +use Appwrite\Client; +use Appwrite\ID; +use Appwrite\Services\DocumentsDB; + +$client = (new Client()) + ->setEndpoint('https://.cloud.appwrite.io/v1') + ->setProject('') + ->setKey(''); + +$documentsDB = new DocumentsDB($client); + +$documentsDB->upsertDocuments( + databaseId: '', + collectionId: '', + documents: [ + [ + '$id' => '', + '$createdAt' => (new DateTime(''))->format(DATE_ATOM), + '$updatedAt' => (new DateTime(''))->format(DATE_ATOM), + // ...your attributes + ], + ] +); +``` +```server-swift +import Appwrite +import Foundation + +let client = Client() + .setEndpoint("https://.cloud.appwrite.io/v1") + .setProject("") + .setKey("") + +let documentsDB = DocumentsDB(client) + +let isoFormatter = ISO8601DateFormatter() +isoFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds] +let createdAt = isoFormatter.string(from: isoFormatter.date(from: "") ?? Date()) +let updatedAt = isoFormatter.string(from: isoFormatter.date(from: "") ?? Date()) + +do { + let bulkUpserted = try await documentsDB.upsertDocuments( + databaseId: "", + collectionId: "", + documents: [ + [ + "$id": "", + "$createdAt": createdAt, + "$updatedAt": updatedAt, + // ...your attributes + ] + ] + ) + print("Bulk upsert:", bulkUpserted) +} catch { + print("Bulk upsert error:", error) +} +``` +```server-ruby +require 'appwrite' +require 'time' + +include Appwrite + +client = Client.new + .set_endpoint('https://.cloud.appwrite.io/v1') + .set_project('') + .set_key('') + +documents_db = DocumentsDB.new(client) + +custom_date = Time.parse('').iso8601 + +documents_db.upsert_documents( + database_id: '', + collection_id: '', + documents: [ + { + '$id' => '', + '$createdAt' => custom_date, + '$updatedAt' => custom_date, + # ...your attributes + } + ] +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndpoint("https://.cloud.appwrite.io/v1") + .SetProject("") + .SetKey(""); + +DocumentsDB documentsDB = new DocumentsDB(client); + +string createdAt = DateTimeOffset.Parse("").ToString("O"); +string updatedAt = DateTimeOffset.Parse("").ToString("O"); + +await documentsDB.UpsertDocuments( + databaseId: "", + collectionId: "", + documents: new List + { + new Dictionary + { + ["$id"] = "", + ["$createdAt"] = createdAt, + ["$updatedAt"] = updatedAt, + // ...your attributes + } + } +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://.cloud.appwrite.io/v1') + .setProject('') + .setKey(''); + +DocumentsDB documentsDB = DocumentsDB(client); + +String createdAt = DateTime.parse('').toIso8601String(); +String updatedAt = DateTime.parse('').toIso8601String(); + +await documentsDB.upsertDocuments( + databaseId: '', + collectionId: '', + documents: [ + { + '\$id': '', + '\$createdAt': createdAt, + '\$updatedAt': updatedAt, + // ...your attributes + } + ], +); +``` +```rust +use appwrite::Client; +use appwrite::services::documents_db::DocumentsDB; +use serde_json::json; + +#[tokio::main] +async fn main() -> Result<(), Box> { + let client = Client::new() + .set_endpoint("https://.cloud.appwrite.io/v1") + .set_project("") + .set_key(""); + + let documents_db = DocumentsDB::new(&client); + + let result = documents_db.upsert_documents( + "", + "", + vec![ + json!({ + "$id": "", + "$createdAt": "2024-01-01T00:00:00.000Z", + "$updatedAt": "2025-01-01T00:00:00.000Z" + // ...your attributes + }), + ], + None, + ).await?; + + println!("Bulk upsert: {:?}", result); + Ok(()) +} +``` +{% /multicode %} + +# Common use cases {% #use-cases %} + +Custom timestamps are particularly useful in several scenarios: + +## Data migration {% #data-migration %} +When migrating existing data from another system, you can preserve the original +creation and modification times: + +{% multicode %} +```server-nodejs +await documentsDB.createDocument({ + databaseId: '', + collectionId: 'blog_posts', + documentId: sdk.ID.unique(), + data: { + '$createdAt': '', + '$updatedAt': '', + title: '', + content: '<CONTENT>' + } +}); +``` +```server-php +$documentsDB->createDocument( + databaseId: '<DATABASE_ID>', + collectionId: 'blog_posts', + documentId: ID::unique(), + data: [ + '$createdAt' => '<ORIGINAL_CREATED_AT_ISO>', + '$updatedAt' => '<LAST_MODIFIED_ISO>', + 'title' => '<TITLE>', + 'content' => '<CONTENT>' + ] +); +``` +```server-swift +let _ = try await documentsDB.createDocument( + databaseId: "<DATABASE_ID>", + collectionId: "blog_posts", + documentId: ID.unique(), + data: [ + "$createdAt": "<ORIGINAL_CREATED_AT_ISO>", + "$updatedAt": "<LAST_MODIFIED_ISO>", + "title": "<TITLE>", + "content": "<CONTENT>" + ] +) +``` +```server-python +documents_db.create_document( + database_id='<DATABASE_ID>', + collection_id='blog_posts', + document_id=ID.unique(), + data={ + '$createdAt': '<ORIGINAL_CREATED_AT_ISO>', + '$updatedAt': '<LAST_MODIFIED_ISO>', + 'title': '<TITLE>', + 'content': '<CONTENT>' + } +) +``` +```server-ruby +documents_db.create_document( + database_id: '<DATABASE_ID>', + collection_id: 'blog_posts', + document_id: ID.unique(), + data: { + '$createdAt' => '<ORIGINAL_CREATED_AT_ISO>', + '$updatedAt' => '<LAST_MODIFIED_ISO>', + 'title' => '<TITLE>', + 'content' => '<CONTENT>' + } +) +``` +```server-dotnet +await documentsDB.CreateDocument( + databaseId: "<DATABASE_ID>", + collectionId: "blog_posts", + documentId: ID.Unique(), + data: new Dictionary<string, object> + { + ["$createdAt"] = "<ORIGINAL_CREATED_AT_ISO>", + ["$updatedAt"] = "<LAST_MODIFIED_ISO>", + ["title"] = "<TITLE>", + ["content"] = "<CONTENT>" + } +); +``` +```server-dart +await documentsDB.createDocument( + databaseId: '<DATABASE_ID>', + collectionId: 'blog_posts', + documentId: ID.unique(), + data: { + '\$createdAt': '<ORIGINAL_CREATED_AT_ISO>', + '\$updatedAt': '<LAST_MODIFIED_ISO>', + 'title': '<TITLE>', + 'content': '<CONTENT>' + }, +); +``` +```rust +use appwrite::Client; +use appwrite::services::documents_db::DocumentsDB; +use appwrite::id::ID; +use serde_json::json; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<API_KEY>"); + + let documents_db = DocumentsDB::new(&client); + + let result = documents_db.create_document( + "<DATABASE_ID>", + "blog_posts", + &ID::unique(), + json!({ + "$createdAt": "<ORIGINAL_CREATED_AT_ISO>", + "$updatedAt": "<LAST_MODIFIED_ISO>", + "title": "<TITLE>", + "content": "<CONTENT>" + }), + None, + None, + ).await?; + + println!("Created: {:?}", result); + Ok(()) +} +``` +{% /multicode %} + +## Backdating records {% #backdating %} +For historical data entry or when creating records that represent past events: + +{% multicode %} +```server-nodejs +await documentsDB.createDocument({ + databaseId: '<DATABASE_ID>', + collectionId: 'transactions', + documentId: sdk.ID.unique(), + data: { + '$createdAt': '2023-12-31T23:59:59.000Z', + '$updatedAt': '2023-12-31T23:59:59.000Z', + amount: 1000, + type: 'year-end-bonus' + } +}); +``` +```server-php +$documentsDB->createDocument( + databaseId: '<DATABASE_ID>', + collectionId: 'transactions', + documentId: ID::unique(), + data: [ + '$createdAt' => '2023-12-31T23:59:59.000Z', + '$updatedAt' => '2023-12-31T23:59:59.000Z', + 'amount' => 1000, + 'type' => 'year-end-bonus' + ] +); +``` +```server-swift +let _ = try await documentsDB.createDocument( + databaseId: "<DATABASE_ID>", + collectionId: "transactions", + documentId: ID.unique(), + data: [ + "$createdAt": "2023-12-31T23:59:59.000Z", + "$updatedAt": "2023-12-31T23:59:59.000Z", + "amount": 1000, + "type": "year-end-bonus" + ] +) +``` +```server-python +documents_db.create_document( + database_id='<DATABASE_ID>', + collection_id='transactions', + document_id=ID.unique(), + data={ + '$createdAt': '2023-12-31T23:59:59.000Z', + '$updatedAt': '2023-12-31T23:59:59.000Z', + 'amount': 1000, + 'type': 'year-end-bonus' + } +) +``` +```server-ruby +documents_db.create_document( + database_id: '<DATABASE_ID>', + collection_id: 'transactions', + document_id: ID.unique(), + data: { + '$createdAt' => '2023-12-31T23:59:59.000Z', + '$updatedAt' => '2023-12-31T23:59:59.000Z', + 'amount' => 1000, + 'type' => 'year-end-bonus' + } +) +``` +```server-dotnet +await documentsDB.CreateDocument( + databaseId: "<DATABASE_ID>", + collectionId: "transactions", + documentId: ID.Unique(), + data: new Dictionary<string, object> + { + ["$createdAt"] = "2023-12-31T23:59:59.000Z", + ["$updatedAt"] = "2023-12-31T23:59:59.000Z", + ["amount"] = 1000, + ["type"] = "year-end-bonus" + } +); +``` +```server-dart +await documentsDB.createDocument( + databaseId: '<DATABASE_ID>', + collectionId: 'transactions', + documentId: ID.unique(), + data: { + '\$createdAt': '2023-12-31T23:59:59.000Z', + '\$updatedAt': '2023-12-31T23:59:59.000Z', + 'amount': 1000, + 'type': 'year-end-bonus' + }, +); +``` +```rust +use appwrite::Client; +use appwrite::services::documents_db::DocumentsDB; +use appwrite::id::ID; +use serde_json::json; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<API_KEY>"); + + let documents_db = DocumentsDB::new(&client); + + let result = documents_db.create_document( + "<DATABASE_ID>", + "transactions", + &ID::unique(), + json!({ + "$createdAt": "2023-12-31T23:59:59.000Z", + "$updatedAt": "2023-12-31T23:59:59.000Z", + "amount": 1000, + "type": "year-end-bonus" + }), + None, + None, + ).await?; + + println!("Created: {:?}", result); + Ok(()) +} +``` +{% /multicode %} + +## Synchronization {% #synchronization %} +When synchronizing data between systems while maintaining timestamp consistency: + +{% multicode %} +```server-nodejs +await documentsDB.upsertDocument({ + databaseId: '<DATABASE_ID>', + collectionId: 'users', + documentId: '<DOCUMENT_ID_OR_NEW_ID>', + data: { + '$updatedAt': '<EXTERNAL_LAST_MODIFIED_ISO>', + profile: '<PROFILE_DATA>' + } +}); +``` +```server-php +$documentsDB->upsertDocument( + databaseId: '<DATABASE_ID>', + collectionId: 'users', + documentId: '<DOCUMENT_ID_OR_NEW_ID>', + data: [ + '$updatedAt' => '<EXTERNAL_LAST_MODIFIED_ISO>', + 'profile' => '<PROFILE_DATA>' + ] +); +``` +```server-swift +let _ = try await documentsDB.upsertDocument( + databaseId: "<DATABASE_ID>", + collectionId: "users", + documentId: "<DOCUMENT_ID_OR_NEW_ID>", + data: [ + "$updatedAt": "<EXTERNAL_LAST_MODIFIED_ISO>", + "profile": "<PROFILE_DATA>" + ] +) +``` +```server-python +documents_db.upsert_document( + database_id='<DATABASE_ID>', + collection_id='users', + document_id='<DOCUMENT_ID_OR_NEW_ID>', + data={ + '$updatedAt': '<EXTERNAL_LAST_MODIFIED_ISO>', + 'profile': '<PROFILE_DATA>' + } +) +``` +```server-ruby +documents_db.upsert_document( + database_id: '<DATABASE_ID>', + collection_id: 'users', + document_id: '<DOCUMENT_ID_OR_NEW_ID>', + data: { + '$updatedAt' => '<EXTERNAL_LAST_MODIFIED_ISO>', + 'profile' => '<PROFILE_DATA>' + } +) +``` +```server-dotnet +await documentsDB.UpsertDocument( + databaseId: "<DATABASE_ID>", + collectionId: "users", + documentId: "<DOCUMENT_ID_OR_NEW_ID>", + data: new Dictionary<string, object> + { + ["$updatedAt"] = "<EXTERNAL_LAST_MODIFIED_ISO>", + ["profile"] = "<PROFILE_DATA>" + } +); +``` +```server-dart +await documentsDB.upsertDocument( + databaseId: '<DATABASE_ID>', + collectionId: 'users', + documentId: '<DOCUMENT_ID_OR_NEW_ID>', + data: { + '\$updatedAt': '<EXTERNAL_LAST_MODIFIED_ISO>', + 'profile': '<PROFILE_DATA>' + }, +); +``` +```rust +use appwrite::Client; +use appwrite::services::documents_db::DocumentsDB; +use serde_json::json; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<API_KEY>"); + + let documents_db = DocumentsDB::new(&client); + + let result = documents_db.upsert_document( + "<DATABASE_ID>", + "users", + "<DOCUMENT_ID_OR_NEW_ID>", + Some(json!({ + "$updatedAt": "<EXTERNAL_LAST_MODIFIED_ISO>", + "profile": "<PROFILE_DATA>" + })), + None, + None, + ).await?; + + println!("Upserted: {:?}", result); + Ok(()) +} +``` +{% /multicode %} + +{% info title="Timestamp format and usage" %} +- Values must be valid ISO 8601 date-time strings (UTC recommended). Using `toISOString()` (JavaScript) or `datetime.isoformat()` (Python) is a good default. +- You can set either or both attributes as needed. If omitted, Appwrite sets them automatically. +{% /info %} diff --git a/src/routes/docs/products/databases/documentsdb/transactions/+page.markdoc b/src/routes/docs/products/databases/documentsdb/transactions/+page.markdoc new file mode 100644 index 00000000000..be64977d0ad --- /dev/null +++ b/src/routes/docs/products/databases/documentsdb/transactions/+page.markdoc @@ -0,0 +1,1274 @@ +--- +layout: article +title: Transactions +description: Stage multiple database operations and commit them atomically. Group changes across databases and collections with ordering, isolation, and conflict detection. +--- + +Transactions let you stage multiple database operations and apply them together, atomically. Use transactions to keep related changes consistent, even when they span multiple databases and collections. + +# How transactions work {% #how-transactions-work %} + +1. Call the [createTransaction](#create-a-transaction) method to create a transaction. This will return a transaction model, including its ID. +2. Stage operations by passing the `transactionId` parameter to supported document, bulk, and atomic numeric methods. You can stage many operations at once with the [createOperations](#create-operations) method. +3. Call the [updateTransaction](#update-transaction) method to commit or roll back. + +On commit, Appwrite replays all staged logs in order inside a real database transaction. Staged operations see earlier staged changes (read your own writes). If any affected document changed outside your transaction, the commit fails with a conflict. + +{% info title="Scope and limitations" %} +You can stage operations across any database and collection within the same transaction. Schema operations (for example, creating or deleting indexes) are not included in transactions. +{% /info %} + +# Limits {% #limits %} + +The maximum number of operations you can stage per transaction depends on your plan: + +| Plan | Max operations per transaction | +|------|-------------------------------| +| Free | 100 | +| Pro | 1,000 | + +# Create a transaction {% #create-a-transaction %} + +Call the `createTransaction` method to begin. It returns a transaction model that includes `$id`. Pass this ID as `transactionId` to subsequent operations. + +{% multicode %} +```client-web +import { Client, DocumentsDB } from 'appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>'); + +const documentsDB = new DocumentsDB(client); + +const tx = await documentsDB.createTransaction(); +// tx.$id is your transactionId +``` +```client-react-native +import { Client, DocumentsDB } from 'react-native-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>'); + +const documentsDB = new DocumentsDB(client); + +const tx = await documentsDB.createTransaction(); +// tx.$id is your transactionId +``` +```client-flutter +import 'package:appwrite/appwrite.dart'; + +final client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>'); + +final documentsDB = DocumentsDB(client); + +final tx = await documentsDB.createTransaction(); +// tx.$id is your transactionId +``` +```client-apple +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + +let documentsDB = DocumentsDB(client) + +let tx = try await documentsDB.createTransaction() +// tx.$id is your transactionId +``` +```client-android-kotlin +import io.appwrite.Client +import io.appwrite.services.DocumentsDB + +val client = Client(applicationContext) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + +val documentsDB = DocumentsDB(client) + +val tx = documentsDB.createTransaction() +// tx.$id is your transactionId +``` +```client-android-java +import io.appwrite.Client; +import io.appwrite.services.DocumentsDB; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>"); + +DocumentsDB documentsDB = new DocumentsDB(client); + +// Create a transaction (asynchronous) +documentsDB.createTransaction(new CoroutineCallback<>((tx, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + System.out.println(tx); +})); +``` +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<API_KEY>'); + +const documentsDB = new sdk.DocumentsDB(client); + +const tx = await documentsDB.createTransaction(); +// tx.$id is your transactionId +``` +```server-deno +import * as sdk from 'npm:node-appwrite'; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<API_KEY>'); + +const documentsDB = new sdk.DocumentsDB(client); + +const tx = await documentsDB.createTransaction(); +// tx.$id is your transactionId +``` +```server-python +from appwrite.client import Client +from appwrite.services.documents_db import DocumentsDB + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<API_KEY>') + +documents_db = DocumentsDB(client) + +tx = documents_db.create_transaction() +# tx.$id is your transactionId +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\DocumentsDB; + +$client = new Client(); + +$client + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<API_KEY>') +; + +$documentsDB = new DocumentsDB($client); + +$tx = $documentsDB->createTransaction(); +// $tx->\$id is your transactionId +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<API_KEY>') + +documents_db = DocumentsDB.new(client) + +tx = documents_db.create_transaction +# tx['$id'] is your transactionId +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +var client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<API_KEY>"); + +var documentsDB = new DocumentsDB(client); + +var tx = await documentsDB.CreateTransaction(); +// tx.$id is your transactionId +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +void main() async { + Client client = Client(); + DocumentsDB documentsDB = DocumentsDB(client); + + client + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<API_KEY>'); + + final tx = await documentsDB.createTransaction(); + // tx contains the transaction ID +} +``` +```server-go +package main + +import ( + "log" + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<API_KEY>"), + ) + + documentsDB := appwrite.NewDocumentsDB(client) + + tx, err := documentsDB.CreateTransaction() + if err != nil { log.Fatal(err) } + _ = tx +} +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<API_KEY>") + +let documentsDB = DocumentsDB(client) + +let tx = try await documentsDB.createTransaction() +// tx.$id is your transactionId +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.DocumentsDB + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<API_KEY>") + +val documentsDB = DocumentsDB(client) + +val tx = documentsDB.createTransaction() +// tx.$id is your transactionId +``` +```server-java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.DocumentsDB; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<API_KEY>"); + +DocumentsDB documentsDB = new DocumentsDB(client); + +documentsDB.createTransaction(new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + System.out.println(result); +})); +``` +```server-rust +use appwrite::Client; +use appwrite::services::documents_db::DocumentsDB; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<API_KEY>"); + + let documents_db = DocumentsDB::new(&client); + + let tx = documents_db.create_transaction(None).await?; + // tx.id is your transaction_id + + Ok(()) +} +``` +{% /multicode %} + +# Stage operations {% #stage-operations %} + +Add the `transactionId` parameter to supported methods to stage them instead of immediately persisting. + +When you pass `transactionId`, Appwrite writes the operation to an internal staging area. The target collection is not modified until you commit the transaction. + +## Stage single operations {% #stage-single-operations %} + +Create, update, upsert, delete, and atomic numeric operations accept `transactionId`, as well as their bulk versions (createDocuments, updateDocuments, upsertDocuments, deleteDocuments). + +{% multicode %} +```client-web +// Create inside a transaction +await documentsDB.createDocument({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + data: { name: 'Walter' }, + transactionId: tx.$id +}); + +// Increment inside a transaction +await documentsDB.incrementDocumentAttribute({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + attribute: 'credits', + value: 1, + transactionId: tx.$id +}); +``` +```client-flutter +// Create inside a transaction +await documentsDB.createDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + data: { 'name': 'Walter' }, + transactionId: tx.$id +); + +// Increment inside a transaction +await documentsDB.incrementDocumentAttribute( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + attribute: 'credits', + value: 1, + transactionId: tx.$id +); +``` +```client-apple +// Create inside a transaction +try await documentsDB.createDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: "<DOCUMENT_ID>", + data: ["name": "Walter"], + transactionId: tx.$id +) + +// Increment inside a transaction +try await documentsDB.incrementDocumentAttribute( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: "<DOCUMENT_ID>", + attribute: "credits", + value: 1, + transactionId: tx.$id +) +``` +```server-kotlin +// Create inside a transaction +documentsDB.createDocument( + databaseId = "<DATABASE_ID>", + collectionId = "<COLLECTION_ID>", + documentId = "<DOCUMENT_ID>", + data = mapOf("name" to "Walter"), + transactionId = tx.$id +) + +// Increment inside a transaction +documentsDB.incrementDocumentAttribute( + databaseId = "<DATABASE_ID>", + collectionId = "<COLLECTION_ID>", + documentId = "<DOCUMENT_ID>", + attribute = "credits", + value = 1, + transactionId = tx.$id +) +``` +```server-java +// Create inside a transaction (asynchronous) +documentsDB.createDocument( + "<DATABASE_ID>", + "<COLLECTION_ID>", + "<DOCUMENT_ID>", + Map.of("name", "Walter"), + "<TRANSACTION_ID>", + new CoroutineCallback<>((document, error) -> { + if (error != null) { + error.printStackTrace(); + return null; + } + System.out.println(document); + return null; + }) +); + +// Increment inside a transaction (asynchronous) +documentsDB.incrementDocumentAttribute( + "<DATABASE_ID>", + "<COLLECTION_ID>", + "<DOCUMENT_ID>", + "credits", + 1, + "<TRANSACTION_ID>", + new CoroutineCallback<>((document, error) -> { + if (error != null) { + error.printStackTrace(); + return null; + } + System.out.println(document); + return null; + }) +); +``` +```client-react-native +// Create inside a transaction +await documentsDB.createDocument({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + data: { name: 'Walter' }, + transactionId: tx.$id +}); + +// Increment inside a transaction +await documentsDB.incrementDocumentAttribute({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + attribute: 'credits', + value: 1, + transactionId: tx.$id +}); +``` +```server-nodejs +// Update inside a transaction +await documentsDB.updateDocument({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + data: { plan: 'pro' }, + transactionId: tx.$id +}); + +// Delete inside a transaction +await documentsDB.deleteDocument({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + transactionId: tx.$id +}); +``` +```server-python +# Upsert inside a transaction +documents_db.upsert_document( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>', + document_id = '<DOCUMENT_ID>', + data = { 'name': 'Walter' }, + transaction_id = tx.id +) + +# Decrement inside a transaction +documents_db.decrement_document_attribute( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>', + document_id = '<DOCUMENT_ID>', + attribute = 'credits', + value = 1, + transaction_id = tx.id +) +``` +```server-php +// Create inside a transaction +$documentsDB->createDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + data: ['name' => 'Walter'], + transactionId: $tx['$id'] +); + +// Increment inside a transaction +$documentsDB->incrementDocumentAttribute( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + attribute: 'credits', + value: 1, + transactionId: $tx['$id'] +); +``` +```server-ruby +# Create inside a transaction +documents_db.create_document( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + document_id: '<DOCUMENT_ID>', + data: { 'name' => 'Walter' }, + transaction_id: tx['$id'] +) + +# Increment inside a transaction +documents_db.increment_document_attribute( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + document_id: '<DOCUMENT_ID>', + attribute: 'credits', + value: 1, + transaction_id: tx['$id'] +) +``` +```server-dotnet +// Create inside a transaction +await documentsDB.CreateDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: "<DOCUMENT_ID>", + data: new Dictionary<string, object> { ["name"] = "Walter" }, + transactionId: tx.Id +); + +// Increment inside a transaction +await documentsDB.IncrementDocumentAttribute( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: "<DOCUMENT_ID>", + attribute: "credits", + value: 1, + transactionId: tx.Id +); +``` +```server-dart +// Create inside a transaction +await documentsDB.createDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + data: { 'name': 'Walter' }, + transactionId: tx.Id +); + +// Increment inside a transaction +await documentsDB.incrementDocumentAttribute( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + attribute: 'credits', + value: 1, + transactionId: tx.Id +); +``` +```server-deno +// Create inside a transaction +await documentsDB.createDocument({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + data: { name: 'Walter' }, + transactionId: tx.$id +}); + +// Increment inside a transaction +await documentsDB.incrementDocumentAttribute({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + attribute: 'credits', + value: 1, + transactionId: tx.$id +}); +``` +```server-swift +// Create inside a transaction +try await documentsDB.createDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: "<DOCUMENT_ID>", + data: ["name": "Walter"], + transactionId: tx.$id +) + +// Increment inside a transaction +try await documentsDB.incrementDocumentAttribute( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: "<DOCUMENT_ID>", + attribute: "credits", + value: 1, + transactionId: tx.$id +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::documents_db::DocumentsDB; +use serde_json::json; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<API_KEY>"); + + let documents_db = DocumentsDB::new(&client); + + let tx = documents_db.create_transaction(None).await?; + + // Update inside a transaction + documents_db.update_document( + "<DATABASE_ID>", + "<COLLECTION_ID>", + "<DOCUMENT_ID>", + Some(json!({ "plan": "pro" })), + None, + Some(&tx.id), + ).await?; + + // Delete inside a transaction + documents_db.delete_document( + "<DATABASE_ID>", + "<COLLECTION_ID>", + "<DOCUMENT_ID>", + Some(&tx.id), + ).await?; + + Ok(()) +} +``` +{% /multicode %} + +## Stage many with createOperations {% #create-operations %} + +Use the `createOperations` method to stage multiple operations across databases and collections in a single request. Provide an array of operation objects: + +```json +[ + { + "action": "create|update|upsert|increment|decrement|delete|bulkCreate|bulkUpdate|bulkUpsert|bulkDelete", + "databaseId": "<DATABASE_ID>", + "collectionId": "<COLLECTION_ID>", + "documentId": "<DOCUMENT_ID>", + "data": {} + } +] +``` + +### Provide data for each action (createOperations) {% #provide-data-for-each-action %} + +### Create, update, and upsert {% #create-update-upsert %} +Pass a raw data object. +```json +{ "name": "Walter" } +``` + +### Increment and decrement {% #increment-decrement %} +Pass a value and optionally `min`/`max` bounds. +```json +{ "value": 1, "min": 0, "max": 1000, "attribute": "<ATTRIBUTE_NAME>" } +``` + +### Bulk create and bulk upsert {% #bulk-create-upsert %} +Pass an array of raw data objects. +```json +[{ "$id": "123", "name": "Walter" }] +``` + +### Bulk update {% #bulk-update %} +Pass queries and the data to apply. +```json +{ "queries": [{"method": "equal", "attribute": "status", "values": ["draft"]}], "data": { "status": "published" } } +``` + +### Bulk delete {% #bulk-delete %} +Pass queries to select documents to delete. +```json +{ "queries": [{"method": "equal", "attribute": "archived", "values": [true]}] } +``` + +{% multicode %} +```server-nodejs +// Stage multiple operations at once +await documentsDB.createOperations({ + transactionId: tx.$id, + operations: [ + { + action: 'create', + databaseId: '<DB_A>', + collectionId: '<COLLECTION_1>', + documentId: 'u1', + data: { name: 'Walter' } + }, + { + action: 'increment', + databaseId: '<DB_B>', + collectionId: '<COLLECTION_2>', + documentId: 'u2', + data: { value: 1, min: 0, attribute: 'credits' } + } + ] +}); +``` +```server-python +documents_db.create_operations( + transaction_id = tx.id, + operations = [ + { + 'action': 'create', + 'databaseId': '<DB_A>', + 'collectionId': '<COLLECTION_1>', + 'documentId': 'u1', + 'data': { 'name': 'Walter' } + }, + { + 'action': 'increment', + 'databaseId': '<DB_B>', + 'collectionId': '<COLLECTION_2>', + 'documentId': 'u2', + 'data': { 'value': 1, 'min': 0, 'attribute': 'credits' } + } + ] +) +``` +```client-web +await documentsDB.createOperations({ + transactionId: tx.$id, + operations: [ + { + action: 'create', + databaseId: '<DB_A>', + collectionId: '<COLLECTION_1>', + documentId: 'u1', + data: { name: 'Walter' } + }, + { + action: 'increment', + databaseId: '<DB_B>', + collectionId: '<COLLECTION_2>', + documentId: 'u2', + data: { value: 1, min: 0, attribute: 'credits' } + } + ] +}); +``` +```client-flutter +await documentsDB.createOperations( + transactionId: tx.$id, + operations: [ + { + 'action': 'create', + 'databaseId': '<DB_A>', + 'collectionId': '<COLLECTION_1>', + 'documentId': 'u1', + 'data': { 'name': 'Walter' } + }, + { + 'action': 'increment', + 'databaseId': '<DB_B>', + 'collectionId': '<COLLECTION_2>', + 'documentId': 'u2', + 'data': { 'value': 1, 'min': 0, 'attribute': 'credits' } + } + ], +); +``` +```client-apple +try await documentsDB.createOperations( + transactionId: tx.$id, + operations: [ + [ + "action": "create", + "databaseId": "<DB_A>", + "collectionId": "<COLLECTION_1>", + "documentId": "u1", + "data": ["name": "Walter"] + ], + [ + "action": "increment", + "databaseId": "<DB_B>", + "collectionId": "<COLLECTION_2>", + "documentId": "u2", + "data": ["value": 1, "min": 0, "attribute": "credits"] + ] + ] +) +``` +```server-kotlin +documentsDB.createOperations( + transactionId = tx.$id, + operations = listOf( + mapOf( + "action" to "create", + "databaseId" to "<DB_A>", + "collectionId" to "<COLLECTION_1>", + "documentId" to "u1", + "data" to mapOf("name" to "Walter") + ), + mapOf( + "action" to "increment", + "databaseId" to "<DB_B>", + "collectionId" to "<COLLECTION_2>", + "documentId" to "u2", + "data" to mapOf("value" to 1, "min" to 0, "attribute" to "credits") + ) + ) +) +``` +```server-java +// Stage multiple operations at once (asynchronous) +List<Map<String, Object>> operations = Arrays.asList( + Map.of( + "action", "create", + "databaseId", "<DB_A>", + "collectionId", "<COLLECTION_1>", + "documentId", "u1", + "data", Map.of("name", "Walter") + ), + Map.of( + "action", "increment", + "databaseId", "<DB_B>", + "collectionId", "<COLLECTION_2>", + "documentId", "u2", + "data", Map.of("value", 1, "min", 0, "attribute", "credits") + ) +); + +documentsDB.createOperations( + "<TRANSACTION_ID>", + operations, + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return null; + } + System.out.println(result); + return null; + }) +); +``` +```client-react-native +await documentsDB.createOperations({ + transactionId: tx.$id, + operations: [ + { + action: 'create', + databaseId: '<DB_A>', + collectionId: '<COLLECTION_1>', + documentId: 'u1', + data: { name: 'Walter' } + }, + { + action: 'increment', + databaseId: '<DB_B>', + collectionId: '<COLLECTION_2>', + documentId: 'u2', + data: { value: 1, min: 0, attribute: 'credits' } + } + ] +}); +``` +```server-deno +await documentsDB.createOperations({ + transactionId: tx.$id, + operations: [ + { + action: 'create', + databaseId: '<DB_A>', + collectionId: '<COLLECTION_1>', + documentId: 'u1', + data: { name: 'Walter' } + }, + { + action: 'increment', + databaseId: '<DB_B>', + collectionId: '<COLLECTION_2>', + documentId: 'u2', + data: { value: 1, min: 0, attribute: 'credits' } + } + ] +}); +``` +```server-php +$documentsDB->createOperations( + transactionId: $tx['$id'], + operations: [ + [ + 'action' => 'create', + 'databaseId' => '<DB_A>', + 'collectionId' => '<COLLECTION_1>', + 'documentId' => 'u1', + 'data' => [ 'name' => 'Walter' ] + ], + [ + 'action' => 'increment', + 'databaseId' => '<DB_B>', + 'collectionId' => '<COLLECTION_2>', + 'documentId' => 'u2', + 'data' => [ 'value' => 1, 'min' => 0, 'attribute' => 'credits' ] + ] + ] +); +``` +```server-ruby +documents_db.create_operations( + transaction_id: tx['$id'], + operations: [ + { + 'action' => 'create', + 'databaseId' => '<DB_A>', + 'collectionId' => '<COLLECTION_1>', + 'documentId' => 'u1', + 'data' => { 'name' => 'Walter' } + }, + { + 'action' => 'increment', + 'databaseId' => '<DB_B>', + 'collectionId' => '<COLLECTION_2>', + 'documentId' => 'u2', + 'data' => { 'value' => 1, 'min' => 0, 'attribute' => 'credits' } + } + ] +) +``` +```server-dotnet +await documentsDB.CreateOperations( + transactionId: tx.Id, + operations: new List<Dictionary<string, object>> + { + new Dictionary<string, object> + { + ["action"] = "create", + ["databaseId"] = "<DB_A>", + ["collectionId"] = "<COLLECTION_1>", + ["documentId"] = "u1", + ["data"] = new Dictionary<string, object> { ["name"] = "Walter" } + }, + new Dictionary<string, object> + { + ["action"] = "increment", + ["databaseId"] = "<DB_B>", + ["collectionId"] = "<COLLECTION_2>", + ["documentId"] = "u2", + ["data"] = new Dictionary<string, object> { ["value"] = 1, ["min"] = 0, ["attribute"] = "credits" } + } + } +); +``` +```server-dart +await documentsDB.createOperations( + transactionId: tx.Id, + operations: [ + { + 'action': 'create', + 'databaseId': '<DB_A>', + 'collectionId': '<COLLECTION_1>', + 'documentId': 'u1', + 'data': { 'name': 'Walter' } + }, + { + 'action': 'increment', + 'databaseId': '<DB_B>', + 'collectionId': '<COLLECTION_2>', + 'documentId': 'u2', + 'data': { 'value': 1, 'min': 0, 'attribute': 'credits' } + } + ] +); +``` +```server-swift +try await documentsDB.createOperations( + transactionId: tx.$id, + operations: [ + [ + "action": "create", + "databaseId": "<DB_A>", + "collectionId": "<COLLECTION_1>", + "documentId": "u1", + "data": ["name": "Walter"] + ], + [ + "action": "increment", + "databaseId": "<DB_B>", + "collectionId": "<COLLECTION_2>", + "documentId": "u2", + "data": ["value": 1, "min": 0, "attribute": "credits"] + ] + ] +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::documents_db::DocumentsDB; +use serde_json::json; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<API_KEY>"); + + let documents_db = DocumentsDB::new(&client); + + let tx = documents_db.create_transaction(None).await?; + + // Stage multiple operations at once + documents_db.create_operations( + &tx.id, + Some(vec![ + json!({ + "action": "create", + "databaseId": "<DB_A>", + "collectionId": "<COLLECTION_1>", + "documentId": "u1", + "data": { "name": "Walter" } + }), + json!({ + "action": "increment", + "databaseId": "<DB_B>", + "collectionId": "<COLLECTION_2>", + "documentId": "u2", + "data": { "value": 1, "min": 0, "attribute": "credits" } + }), + ]), + ).await?; + + Ok(()) +} +``` +{% /multicode %} + +# Commit or roll back {% #commit-or-rollback %} + +When you are done staging operations, call the `updateTransaction` method to finalize the transaction. + +{% multicode %} +```client-web +// Commit +await documentsDB.updateTransaction({ + transactionId: tx.$id, + commit: true +}); + +// Or roll back +await documentsDB.updateTransaction({ + transactionId: tx.$id, + rollback: true +}); +``` +```client-flutter +// Commit +await documentsDB.updateTransaction( + transactionId: tx.$id, + commit: true +); + +// Roll back +await documentsDB.updateTransaction( + transactionId: tx.$id, + rollback: true +); +``` +```client-apple +// Commit +try await documentsDB.updateTransaction( + transactionId: tx.$id, + commit: true +) + +// Roll back +try await documentsDB.updateTransaction( + transactionId: tx.$id, + rollback: true +) +``` +```server-kotlin +// Commit +documentsDB.updateTransaction( + transactionId = tx.$id, + commit = true +) + +// Roll back +documentsDB.updateTransaction( + transactionId = tx.$id, + rollback = true +) +``` +```server-java +// Commit (asynchronous) +documentsDB.updateTransaction( + "<TRANSACTION_ID>", + true, + false, + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return null; + } + System.out.println(result); + return null; + }) +); + +// Roll back (asynchronous) +documentsDB.updateTransaction( + "<TRANSACTION_ID>", + false, + true, + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return null; + } + System.out.println(result); + return null; + }) +); +``` +```client-react-native +// Commit +await documentsDB.updateTransaction({ + transactionId: tx.$id, + commit: true +}); + +// Roll back +await documentsDB.updateTransaction({ + transactionId: tx.$id, + rollback: true +}); +``` +```server-nodejs +// Commit +await documentsDB.updateTransaction({ + transactionId: tx.$id, + commit: true +}); + +// Roll back +await documentsDB.updateTransaction({ + transactionId: tx.$id, + rollback: true +}); +``` +```server-python +# Commit +documents_db.update_transaction( + transaction_id = tx.id, + commit = True +) + +# Roll back +documents_db.update_transaction( + transaction_id = tx.id, + rollback = True +) +``` +```server-php +// Commit +$documentsDB->updateTransaction( + transactionId: $tx['$id'], + commit: true +); + +// Roll back +$documentsDB->updateTransaction( + transactionId: $tx['$id'], + rollback: true +); +``` +```server-ruby +# Commit +documents_db.update_transaction( + transaction_id: tx['$id'], + commit: true +) + +# Roll back +documents_db.update_transaction( + transaction_id: tx['$id'], + rollback: true +) +``` +```server-dotnet +// Commit +await documentsDB.UpdateTransaction( + transactionId: tx.Id, + commit: true +); + +// Roll back +await documentsDB.UpdateTransaction( + transactionId: tx.Id, + rollback: true +); +``` +```server-dart +// Commit +await documentsDB.updateTransaction( + transactionId: tx.Id, + commit: true +); + +// Roll back +await documentsDB.updateTransaction( + transactionId: tx.Id, + rollback: true +); +``` +```server-rust +use appwrite::Client; +use appwrite::services::documents_db::DocumentsDB; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<API_KEY>"); + + let documents_db = DocumentsDB::new(&client); + + // Commit + documents_db.update_transaction( + "<TRANSACTION_ID>", + Some(true), + None, + ).await?; + + // Roll back + documents_db.update_transaction( + "<TRANSACTION_ID>", + None, + Some(true), + ).await?; + + Ok(()) +} +``` +{% /multicode %} + +# Handle conflicts {% #handle-conflicts %} + +On commit, Appwrite verifies that documents affected by your transaction haven't changed externally since they were staged. If a conflicting change is detected, the commit fails with a conflict error. Resolve the conflict (for example, refetch and re-stage) and try again. + +{% info title="Best practices" %} +Keep transactions short-lived to reduce the likelihood of conflicts. Stage related updates in the order they must be applied. Prefer `createOperations` when you need to stage many changes across multiple collections. +{% /info %} + +{% arrow_link href="/docs/references" %} +Explore the API references +{% /arrow_link %} diff --git a/src/routes/docs/products/databases/tablesdb/backups/+page.markdoc b/src/routes/docs/products/databases/tablesdb/backups/+page.markdoc index 202133529f6..6dca288f054 100644 --- a/src/routes/docs/products/databases/tablesdb/backups/+page.markdoc +++ b/src/routes/docs/products/databases/tablesdb/backups/+page.markdoc @@ -8,14 +8,14 @@ Appwrite Backups enable seamless, **encrypted** database backups on Cloud. All backups are **hot** backups, ensuring zero downtime and fast recovery. Learn how to efficiently back up your databases to ensure data security and smooth recovery. -{% info title="Backups are available on Appwrite Cloud for all Pro, Scale, and Enterprise customers." %} +{% info title="Backups are available on Appwrite Cloud for all Pro and Enterprise customers." %} {% /info %} Appwrite Backups allow you to automate database backups using backup policies, supporting pre-defined, custom retention & other options. You can also create manual backups whenever necessary. # Backup policies {% #backup-policies %} -Backup policies allow you to automate your backup process. The Scale and Enterprise plans allow for more customization and offer options like how often backups should occur, how long they should be retained, and when they should run. +Backup policies allow you to automate your backup process. The Enterprise plan allows for more customization and offers options like how often backups should occur, how long they should be retained, and when they should run. ## Creating a backup policy {% #creating-backup-policy %} @@ -40,21 +40,21 @@ To automate your database backups, you need to create backup policies that run a ![Pro plan policy](/images/docs/databases/pro-policy.avif) {% /only_light %} - * On **Scale** and **Enterprise** plans, you get access to more & custom policies\ + * On the **Enterprise** plan, you get access to more & custom policies\   * Select a pre-defined policy {% only_dark %} - ![Scale plan policies](/images/docs/databases/dark/scale-policies.avif) + ![Backup policies](/images/docs/databases/dark/scale-policies.avif) {% /only_dark %} {% only_light %} - ![Scale plan policies](/images/docs/databases/scale-policies.avif) + ![Backup policies](/images/docs/databases/scale-policies.avif) {% /only_light %} * Or create a custom policy and adjust the settings as you like {% only_dark %} - ![Custom policies for Scale plan](/images/docs/databases/dark/scale-custom-policies.avif) + ![Custom backup policies](/images/docs/databases/dark/scale-custom-policies.avif) {% /only_dark %} {% only_light %} - ![Custom policies for Scale plan](/images/docs/databases/scale-custom-policies.avif) + ![Custom backup policies](/images/docs/databases/scale-custom-policies.avif) {% /only_light %} 4. Click on **Create** diff --git a/src/routes/docs/products/databases/tablesdb/bulk-operations/+page.markdoc b/src/routes/docs/products/databases/tablesdb/bulk-operations/+page.markdoc index 07a93db88c0..d1574894303 100644 --- a/src/routes/docs/products/databases/tablesdb/bulk-operations/+page.markdoc +++ b/src/routes/docs/products/databases/tablesdb/bulk-operations/+page.markdoc @@ -56,10 +56,10 @@ const client = new sdk.Client() const tablesDB = new sdk.TablesDB(client); -const result = await tablesDB.createRows( - '<DATABASE_ID>', - '<TABLE_ID>', - [ +const result = await tablesDB.createRows({ + databaseId: '<DATABASE_ID>', + tableId: '<TABLE_ID>', + rows: [ { $id: sdk.ID.unique(), name: 'Row 1' @@ -69,7 +69,7 @@ const result = await tablesDB.createRows( name: 'Row 2' } ] -); +}); ``` ```server-python @@ -155,16 +155,16 @@ const client = new sdk.Client() const tablesDB = new sdk.TablesDB(client); -const result = await tablesDB.updateRows( - '<DATABASE_ID>', - '<TABLE_ID>', - { +const result = await tablesDB.updateRows({ + databaseId: '<DATABASE_ID>', + tableId: '<TABLE_ID>', + data: { status: 'published' }, - [ + queries: [ sdk.Query.equal('status', 'draft') ] -); +}); ``` ```server-python @@ -242,10 +242,10 @@ const client = new sdk.Client() const tablesDB = new sdk.TablesDB(client); -const result = await tablesDB.upsertRows( - '<DATABASE_ID>', - '<TABLE_ID>', - [ +const result = await tablesDB.upsertRows({ + databaseId: '<DATABASE_ID>', + tableId: '<TABLE_ID>', + rows: [ { $id: sdk.ID.unique(), name: 'New Row 1' @@ -255,7 +255,7 @@ const result = await tablesDB.upsertRows( name: 'New Row 2' } ] -); +}); ``` ```server-python @@ -342,13 +342,13 @@ const client = new sdk.Client() const tablesDB = new sdk.TablesDB(client); -const result = await tablesDB.deleteRows( - '<DATABASE_ID>', - '<TABLE_ID>', - [ +const result = await tablesDB.deleteRows({ + databaseId: '<DATABASE_ID>', + tableId: '<TABLE_ID>', + queries: [ sdk.Query.equal('status', 'archived') ] -); +}); ``` ```server-python diff --git a/static/images/docs/databases/documentsdb/backup-policy.avif b/static/images/docs/databases/documentsdb/backup-policy.avif new file mode 100644 index 0000000000000000000000000000000000000000..b44ed9afa6b3e8dbd4a45a3d1314fe7a17e6a405 GIT binary patch literal 10913 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 literal 0 HcmV?d00001 diff --git a/static/images/docs/databases/documentsdb/backups-tab.avif b/static/images/docs/databases/documentsdb/backups-tab.avif new file mode 100644 index 0000000000000000000000000000000000000000..29aec532bc7a20143dbfba8f340e88218acaea61 GIT binary patch literal 26847 zcmXu}V~{Y+&NYmVZQHhO+qP|cuCZ;~wr$(CZGZQE&Uw?-Sy`!6CBM>LsQ>@~;F!61 zIvBcHngRSLww7j$|Fdl^4gbeiZB1Pa|L6Zt2rW!(oc@0%0Dyy~vCIFn{~y9RSi0E$ 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 J4&(`B2i)Q|INSgL literal 0 HcmV?d00001 diff --git a/static/images/docs/databases/documentsdb/create-database.avif b/static/images/docs/databases/documentsdb/create-database.avif new file mode 100644 index 0000000000000000000000000000000000000000..4a201bf95547debc4f5f8d931de7205d21a73584 GIT binary patch literal 31320 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%0D85z4Fh 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 Bkput$ literal 0 HcmV?d00001 diff --git a/static/images/docs/databases/documentsdb/dark/backup-policy.avif b/static/images/docs/databases/documentsdb/dark/backup-policy.avif new file mode 100644 index 0000000000000000000000000000000000000000..3e152f6732d9433fda4ff81a128f36f369f710df GIT binary patch literal 11350 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%0D4Hoc}@2Pe9?K-Q|_V?$R8!{Lq3@H_8eG2 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 F{|_n$*Mk56 literal 0 HcmV?d00001 diff --git a/static/images/docs/databases/documentsdb/dark/backups-tab.avif b/static/images/docs/databases/documentsdb/dark/backups-tab.avif new file mode 100644 index 0000000000000000000000000000000000000000..b975ab60a2a1cc63ae0e2471459a75445a4ccb14 GIT binary patch literal 28535 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 literal 0 HcmV?d00001 diff --git a/static/images/docs/databases/documentsdb/dark/create-database.avif b/static/images/docs/databases/documentsdb/dark/create-database.avif new file mode 100644 index 0000000000000000000000000000000000000000..8cfe52aa5ed6d505ef2ba868a2d912a96254e201 GIT binary patch literal 34142 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 BF*pDK literal 0 HcmV?d00001 diff --git a/static/images/docs/databases/documentsdb/dark/manual-backup.avif b/static/images/docs/databases/documentsdb/dark/manual-backup.avif new file mode 100644 index 0000000000000000000000000000000000000000..091f73911ed07848eba43d1d18e6857783484a53 GIT binary patch literal 10490 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 literal 0 HcmV?d00001 diff --git a/static/images/docs/databases/documentsdb/manual-backup.avif b/static/images/docs/databases/documentsdb/manual-backup.avif new file mode 100644 index 0000000000000000000000000000000000000000..0dc1a93e6dbfa5870d407fe42bb3f109530c0d60 GIT binary patch literal 10120 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 Vl+cu#7+ZGm)Cah&Z{k7w|3AL_cIyBD literal 0 HcmV?d00001 From 424e023486b54d5513616b58f4d6a0dedaf332eb Mon Sep 17 00:00:00 2001 From: Atharva Deosthale <atharva.deosthale17@gmail.com> Date: Wed, 1 Jul 2026 19:19:53 +0530 Subject: [PATCH 3/8] Add VectorsDB documentation section --- .../databases/vectorsdb/+layout.svelte | 76 +- .../databases/vectorsdb/+page.markdoc | 24 +- .../databases/vectorsdb/backups/+page.markdoc | 89 + .../vectorsdb/bulk-operations/+page.markdoc | 475 +++++ .../vectorsdb/collections/+page.markdoc | 1144 ++++++++++ .../vectorsdb/csv-exports/+page.markdoc | 102 + .../vectorsdb/csv-imports/+page.markdoc | 118 ++ .../vectorsdb/databases/+page.markdoc | 975 +++++++++ .../vectorsdb/documents/+page.markdoc | 1541 ++++++++++++++ .../vectorsdb/embeddings/+page.markdoc | 612 ++++++ .../databases/vectorsdb/order/+page.markdoc | 1006 +++++++++ .../vectorsdb/pagination/+page.markdoc | 1041 +++++++++ .../vectorsdb/permissions/+page.markdoc | 1241 +++++++++++ .../databases/vectorsdb/queries/+page.markdoc | 1879 +++++++++++++++++ .../vectorsdb/quick-start/+page.markdoc | 1034 +++++++++ .../timestamp-overrides/+page.markdoc | 1302 ++++++++++++ .../vectorsdb/transactions/+page.markdoc | 1240 +++++++++++ .../vectorsdb/vector-search/+page.markdoc | 556 +++++ 18 files changed, 14451 insertions(+), 4 deletions(-) create mode 100644 src/routes/docs/products/databases/vectorsdb/backups/+page.markdoc create mode 100644 src/routes/docs/products/databases/vectorsdb/bulk-operations/+page.markdoc create mode 100644 src/routes/docs/products/databases/vectorsdb/collections/+page.markdoc create mode 100644 src/routes/docs/products/databases/vectorsdb/csv-exports/+page.markdoc create mode 100644 src/routes/docs/products/databases/vectorsdb/csv-imports/+page.markdoc create mode 100644 src/routes/docs/products/databases/vectorsdb/databases/+page.markdoc create mode 100644 src/routes/docs/products/databases/vectorsdb/documents/+page.markdoc create mode 100644 src/routes/docs/products/databases/vectorsdb/embeddings/+page.markdoc create mode 100644 src/routes/docs/products/databases/vectorsdb/order/+page.markdoc create mode 100644 src/routes/docs/products/databases/vectorsdb/pagination/+page.markdoc create mode 100644 src/routes/docs/products/databases/vectorsdb/permissions/+page.markdoc create mode 100644 src/routes/docs/products/databases/vectorsdb/queries/+page.markdoc create mode 100644 src/routes/docs/products/databases/vectorsdb/quick-start/+page.markdoc create mode 100644 src/routes/docs/products/databases/vectorsdb/timestamp-overrides/+page.markdoc create mode 100644 src/routes/docs/products/databases/vectorsdb/transactions/+page.markdoc create mode 100644 src/routes/docs/products/databases/vectorsdb/vector-search/+page.markdoc diff --git a/src/routes/docs/products/databases/vectorsdb/+layout.svelte b/src/routes/docs/products/databases/vectorsdb/+layout.svelte index bd502da28b6..174edc4ed4e 100644 --- a/src/routes/docs/products/databases/vectorsdb/+layout.svelte +++ b/src/routes/docs/products/databases/vectorsdb/+layout.svelte @@ -6,7 +6,7 @@ const parent: NavParent = { href: '/docs/products/databases', - label: 'Databases' + label: 'VectorsDB' }; const navigation: NavTree = [ @@ -16,6 +16,80 @@ { label: 'Overview', href: '/docs/products/databases/vectorsdb' + }, + { + label: 'Quick start', + href: '/docs/products/databases/vectorsdb/quick-start' + } + ] + }, + { + label: 'Concepts', + items: [ + { + label: 'Databases', + href: '/docs/products/databases/vectorsdb/databases' + }, + { + label: 'Collections', + href: '/docs/products/databases/vectorsdb/collections' + }, + { + label: 'Documents', + href: '/docs/products/databases/vectorsdb/documents' + }, + { + label: 'Embeddings', + href: '/docs/products/databases/vectorsdb/embeddings' + }, + { + label: 'Permissions', + href: '/docs/products/databases/vectorsdb/permissions' + }, + { + label: 'Queries', + href: '/docs/products/databases/vectorsdb/queries' + }, + { + label: 'Order', + href: '/docs/products/databases/vectorsdb/order' + }, + { + label: 'Backups', + href: '/docs/products/databases/vectorsdb/backups' + } + ] + }, + { + label: 'Journeys', + items: [ + { + label: 'Pagination', + href: '/docs/products/databases/vectorsdb/pagination' + }, + { + label: 'Vector search', + href: '/docs/products/databases/vectorsdb/vector-search' + }, + { + label: 'Transactions', + href: '/docs/products/databases/vectorsdb/transactions' + }, + { + label: 'Bulk operations', + href: '/docs/products/databases/vectorsdb/bulk-operations' + }, + { + label: 'Timestamp overrides', + href: '/docs/products/databases/vectorsdb/timestamp-overrides' + }, + { + label: 'CSV imports', + href: '/docs/products/databases/vectorsdb/csv-imports' + }, + { + label: 'CSV exports', + href: '/docs/products/databases/vectorsdb/csv-exports' } ] } diff --git a/src/routes/docs/products/databases/vectorsdb/+page.markdoc b/src/routes/docs/products/databases/vectorsdb/+page.markdoc index f0391bc33d3..dcc7f83401f 100644 --- a/src/routes/docs/products/databases/vectorsdb/+page.markdoc +++ b/src/routes/docs/products/databases/vectorsdb/+page.markdoc @@ -4,8 +4,26 @@ title: VectorsDB description: Store vector embeddings and run similarity search with Appwrite VectorsDB to power semantic search, recommendations, and other AI features. --- -Appwrite VectorsDB stores vector embeddings and runs similarity search, so you can build semantic search, recommendations, and other AI features. It also exposes an endpoint to generate text embeddings, and shares the permissions, indexes, transactions, and realtime concepts used across Appwrite Databases. +Appwrite VectorsDB lets you store vector embeddings and run similarity search over them. +A collection is created with a fixed `dimension`, every document holds an `embeddings` vector of that length plus optional `metadata`, and an HNSW index keeps similarity search fast as your data grows. -{% info title="Documentation in progress" %} -Detailed VectorsDB guides are on the way. For now, the concepts in [TablesDB](/docs/products/databases/tablesdb) are the closest reference. +{% info title="Looking for file storage?" %} +Databases store data, if you need to store files like images, PDFs or videos, use [Appwrite Storage](/docs/products/storage). {% /info %} + +You organize data into databases, collections, and documents, the same way you do across Appwrite Databases. What sets VectorsDB apart is the fixed schema built for vectors and the ability to generate text embeddings and search by similarity. + +# Key concepts {% #key-concepts %} +[Collections](/docs/products/databases/vectorsdb/collections) are created with a required `dimension`, the length of the vectors they hold. Instead of a typed-attribute schema, every collection is provisioned with a fixed shape: a required `embeddings` vector and an optional `metadata` object. + +[Documents](/docs/products/databases/vectorsdb/documents) store a single embedding under `embeddings` and any associated JSON under `metadata`. The embedding length must match the collection's `dimension`. + +[Embeddings](/docs/products/databases/vectorsdb/embeddings) can be generated from text with built-in models, so you can turn strings into vectors and store them without running a separate embedding service. + +[Vector search](/docs/products/databases/vectorsdb/vector-search) ranks documents by how close their `embeddings` are to a query vector. You create an HNSW index on the `embeddings` field, then pass a vector query to list documents by cosine, dot product, or Euclidean distance. + +VectorsDB also shares the [permissions](/docs/products/databases/vectorsdb/permissions), [queries](/docs/products/databases/vectorsdb/queries), [pagination](/docs/products/databases/vectorsdb/pagination), [transactions](/docs/products/databases/vectorsdb/transactions), and [bulk operations](/docs/products/databases/vectorsdb/bulk-operations) used across Appwrite Databases. + +{% arrow_link href="/docs/products/databases/vectorsdb/quick-start" %} +Quick start +{% /arrow_link %} diff --git a/src/routes/docs/products/databases/vectorsdb/backups/+page.markdoc b/src/routes/docs/products/databases/vectorsdb/backups/+page.markdoc new file mode 100644 index 00000000000..745a382dc09 --- /dev/null +++ b/src/routes/docs/products/databases/vectorsdb/backups/+page.markdoc @@ -0,0 +1,89 @@ +--- +layout: article +title: Backups +description: Learn how to back up and restore your VectorsDB databases, ensuring data security and seamless recovery. +--- + +Appwrite Backups enable seamless, **encrypted** database backups. +All backups are **hot** backups, ensuring zero downtime and fast recovery. + +{% info title="Backups are available for all Pro and Enterprise customers." %} +{% /info %} + +You manage backups from a database's **Backups** tab, where you can automate backups with policies or create manual backups on demand. A backup captures the database along with its collections, documents, and embeddings. + +{% only_dark %} +![Backups tab](/images/docs/databases/documentsdb/dark/backups-tab.avif) +{% /only_dark %} +{% only_light %} +![Backups tab](/images/docs/databases/documentsdb/backups-tab.avif) +{% /only_light %} + +# Backup policies {% #backup-policies %} + +Backup policies automate your backups on a schedule. To create one, open your database's **Backups** tab and click **Create policy**, then choose a preset policy or add a custom one. + +{% only_dark %} +![Create backup policy](/images/docs/databases/documentsdb/dark/backup-policy.avif) +{% /only_dark %} +{% only_light %} +![Create backup policy](/images/docs/databases/documentsdb/backup-policy.avif) +{% /only_light %} + +The available options depend on your plan: + +- On the **Pro** plan, you get a **Daily** backup policy retained for 7 days. +- On the **Enterprise** plan, you get access to additional preset policies and custom policies, where you control how often backups run and how long they are retained. + +Click **Create** to save the policy. Your database is now set up for automated backups. + +# Manual backups {% #manual-backups %} + +You can create an on-demand backup whenever necessary. In your database's **Backups** tab, click **Manual backup**, then click **Create**. + +{% only_dark %} +![Manual backup](/images/docs/databases/documentsdb/dark/manual-backup.avif) +{% /only_dark %} +{% only_light %} +![Manual backup](/images/docs/databases/documentsdb/manual-backup.avif) +{% /only_light %} + +Manual backups are retained until you delete them. Depending on the size of your database, the backup may take some time to complete. You can monitor its progress in the backups list. + +# Restoring backups {% #restoring-backups %} + +To restore a database, you need an existing backup. + +1. Open your database's **Backups** tab. +2. In the backups list, open the **Actions** menu for the backup you want to restore. +3. Click **Restore**. +4. Enter a name for the new database and an optional database ID. +5. Click **Restore**. + +Depending on the size of your database, the restoration may take some time. The restore creates a new database from the backup, leaving the original untouched. + +# Backup security & performance {% #backup-security-and-performance %} + +All backups created with Appwrite are: + +1. **Encrypted**: + All backups are securely encrypted to ensure your data remains protected at all times. + +2. **Remotely stored**: + Backups are stored in a remote location, providing an additional layer of security and ensuring your data is always recoverable. + +3. **Hot backups**: + Backups are hot, meaning they occur with zero downtime, allowing you to recover data quickly without interrupting your projects and services. + +# Best practices {% #best-practices %} + +To ensure your backups are robust and effective, consider the following best practices: + +1. **Schedule regular backups**: + Add backup policies based on the frequency of database changes. Daily backups are often sufficient for most use cases. + +2. **Retain critical backups longer**: + Use custom policies with longer retention to keep backups of critical data for extended periods, ensuring historical records are available when needed. + +3. **Optimize backup policies based on data sensitivity**: + Tailor your backup frequency and retention settings according to the sensitivity and importance of the data. diff --git a/src/routes/docs/products/databases/vectorsdb/bulk-operations/+page.markdoc b/src/routes/docs/products/databases/vectorsdb/bulk-operations/+page.markdoc new file mode 100644 index 00000000000..d7c7e15950e --- /dev/null +++ b/src/routes/docs/products/databases/vectorsdb/bulk-operations/+page.markdoc @@ -0,0 +1,475 @@ +--- +layout: article +title: Bulk operations +description: Perform bulk operations on documents within your collections for efficient data handling in Appwrite VectorsDB. +--- + +Appwrite VectorsDB supports bulk operations for documents, allowing you to create, update, or delete multiple documents in a single request. This can significantly improve performance for apps as it allows you to reduce the number of API calls needed while working with large data sets. + +Bulk operations can only be performed via the server-side SDKs. The client-side SDKs do not support bulk operations by design to prevent abuse and protect against unexpected costs. This ensures that only trusted server environments can perform large-scale data operations. + +For client applications that need bulk-like functionality, consider using [Appwrite Functions](/docs/products/functions) with proper rate limiting and validation. + +Each document's data follows the fixed schema provisioned by its collection: an `embeddings` vector whose length must equal the collection's `dimension`, and an optional free-form `metadata` object. The examples on this page use a collection with `dimension: 4` to keep the arrays readable. + +{% info title="Important notes" %} +Bulk operations trigger Functions, Webhooks, or Realtime events for each document manipulated. Rather than a single event for the entire bulk operation, each document generates a separate event on the existing realtime channels for its operation type. +{% /info %} + +# Atomic behavior {% #atomic-behavior %} + +Bulk operations in Appwrite are **atomic**, meaning they follow an all-or-nothing approach. Either all documents in your bulk request succeed, or all documents fail. + +This atomicity ensures: +- **Data consistency**: Your database remains in a consistent state even if some operations would fail. +- **Race condition prevention**: Multiple clients can safely perform bulk operations simultaneously. +- **Simplified error handling**: You only need to handle complete success or complete failure scenarios. + +For example, if you attempt to create 100 documents and one fails due to a validation error, none of the 100 documents will be created. + +# Plan limits {% #plan-limits %} + +Bulk operations have different limits based on your Appwrite plan: + +| Plan | Documents per request | +|------|----------------------| +| Free | 100 | +| Pro | 1,000 | + +These limits apply to all bulk operations including create, update, upsert, and delete operations. If you need higher limits than what the Pro plan offers, you can [inquire](/contact-us/enterprise) about a custom plan. + +# Create documents {% #create-documents %} + +You can create multiple documents in a single request using the `createDocuments` method. + +{% info title="Custom timestamps" %} +When creating, updating or upserting in bulk, you can set `$createdAt` and `$updatedAt` for each document in the payload. Values must be ISO 8601 date-time strings. If omitted, Appwrite sets them automatically. +{% /info %} + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<API_KEY>'); + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.createDocuments({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documents: [ + { + $id: sdk.ID.unique(), + embeddings: [0.12, 0.84, 0.33, 0.57], + metadata: { title: 'Hamlet', genre: 'tragedy' } + }, + { + $id: sdk.ID.unique(), + embeddings: [0.91, 0.22, 0.14, 0.65], + metadata: { title: 'Macbeth', genre: 'tragedy' } + } + ] +}); +``` + +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB +from appwrite.id import ID + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<API_KEY>') + +vectors_db = VectorsDB(client) + +result = vectors_db.create_documents( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>', + documents = [ + { + '$id': ID.unique(), + 'embeddings': [0.12, 0.84, 0.33, 0.57], + 'metadata': { 'title': 'Hamlet', 'genre': 'tragedy' } + }, + { + '$id': ID.unique(), + 'embeddings': [0.91, 0.22, 0.14, 0.65], + 'metadata': { 'title': 'Macbeth', 'genre': 'tragedy' } + } + ] +) +``` + +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; +use appwrite::id::ID; +use serde_json::json; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); + client.set_project("<PROJECT_ID>"); + client.set_key("<API_KEY>"); + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.create_documents( + "<DATABASE_ID>", + "<COLLECTION_ID>", + vec![ + json!({ + "$id": ID::unique(), + "embeddings": [0.12, 0.84, 0.33, 0.57], + "metadata": { "title": "Hamlet", "genre": "tragedy" } + }), + json!({ + "$id": ID::unique(), + "embeddings": [0.91, 0.22, 0.14, 0.65], + "metadata": { "title": "Macbeth", "genre": "tragedy" } + }), + ], + ).await?; + + Ok(()) +} +``` + +{% /multicode %} + +# Update documents {% #update-documents %} + +{% info title="Permissions required" %} +You must grant **update** permissions to users at the **collection level** before users can update documents. +[Learn more about permissions](/docs/products/databases/vectorsdb/permissions) +{% /info %} + +You can update multiple documents in a single request using the `updateDocuments` method. Pass the fields to change in `data`, and use `queries` to select which documents are affected. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<API_KEY>'); + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.updateDocuments({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + data: { + metadata: { genre: 'drama' } + }, + queries: [ + sdk.Query.equal('metadata.genre', 'tragedy') + ] +}); +``` + +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB +from appwrite.query import Query + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<API_KEY>') + +vectors_db = VectorsDB(client) + +result = vectors_db.update_documents( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>', + data = { + 'metadata': { 'genre': 'drama' } + }, + queries = [ + Query.equal('metadata.genre', 'tragedy') + ] +) +``` + +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; +use appwrite::query::Query; +use serde_json::json; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); + client.set_project("<PROJECT_ID>"); + client.set_key("<API_KEY>"); + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.update_documents( + "<DATABASE_ID>", + "<COLLECTION_ID>", + Some(json!({ + "metadata": { "genre": "drama" } + })), + Some(vec![ + Query::equal("metadata.genre", "tragedy").to_string(), + ]), + None, + ).await?; + + Ok(()) +} +``` + +{% /multicode %} + +# Upsert documents {% #upsert-documents %} + +{% info title="Permissions required" %} +You must grant **create** and **update** permissions to users at the **collection level** before users can create documents. +[Learn more about permissions](/docs/products/databases/vectorsdb/permissions) +{% /info %} + +You can upsert multiple documents in a single request using the `upsertDocuments` method. Documents with a new `$id` are created, while documents with an existing `$id` are updated. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<API_KEY>'); + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.upsertDocuments({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documents: [ + { + $id: sdk.ID.unique(), + embeddings: [0.40, 0.40, 0.40, 0.40], + metadata: { title: 'Othello', genre: 'tragedy' } + }, + { + $id: 'document-id-2', // Existing document ID + embeddings: [0.10, 0.10, 0.10, 0.10], + metadata: { title: 'Hamlet', genre: 'tragedy' } + } + ] +}); +``` + +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB +from appwrite.id import ID + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<API_KEY>') + +vectors_db = VectorsDB(client) + +result = vectors_db.upsert_documents( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>', + documents = [ + { + '$id': ID.unique(), + 'embeddings': [0.40, 0.40, 0.40, 0.40], + 'metadata': { 'title': 'Othello', 'genre': 'tragedy' } + }, + { + '$id': 'document-id-2', # Existing document ID + 'embeddings': [0.10, 0.10, 0.10, 0.10], + 'metadata': { 'title': 'Hamlet', 'genre': 'tragedy' } + } + ] +) +``` + +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; +use appwrite::id::ID; +use serde_json::json; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); + client.set_project("<PROJECT_ID>"); + client.set_key("<API_KEY>"); + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.upsert_documents( + "<DATABASE_ID>", + "<COLLECTION_ID>", + vec![ + json!({ + "$id": ID::unique(), + "embeddings": [0.40, 0.40, 0.40, 0.40], + "metadata": { "title": "Othello", "genre": "tragedy" } + }), + json!({ + "$id": "document-id-2", // Existing document ID + "embeddings": [0.10, 0.10, 0.10, 0.10], + "metadata": { "title": "Hamlet", "genre": "tragedy" } + }), + ], + None, + ).await?; + + Ok(()) +} +``` + +{% /multicode %} + +# Delete documents {% #delete-documents %} + +{% info title="Permissions required" %} +You must grant **delete** permissions to users at the **collection level** before users can delete documents. +[Learn more about permissions](/docs/products/databases/vectorsdb/permissions) +{% /info %} + +You can delete multiple documents in a single request using the `deleteDocuments` method. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<API_KEY>'); + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.deleteDocuments({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + sdk.Query.equal('metadata.genre', 'drama') + ] +}); +``` + +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB +from appwrite.query import Query + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<API_KEY>') + +vectors_db = VectorsDB(client) + +result = vectors_db.delete_documents( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>', + queries = [ + Query.equal('metadata.genre', 'drama') + ] +) +``` + +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; +use appwrite::query::Query; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); + client.set_project("<PROJECT_ID>"); + client.set_key("<API_KEY>"); + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.delete_documents( + "<DATABASE_ID>", + "<COLLECTION_ID>", + Some(vec![ + Query::equal("metadata.genre", "drama").to_string(), + ]), + None, + ).await?; + + Ok(()) +} +``` + +{% /multicode %} + +{% info title="Queries for deletion" %} + +When deleting documents, you must specify queries to filter which documents to delete. +If no queries are provided, all documents in the collection will be deleted. +[Learn more about queries](/docs/products/databases/vectorsdb/queries). + +{% /info %} + +# Use transactions {% #use-transactions %} + +`updateDocuments`, `upsertDocuments`, and `deleteDocuments` accept a `transactionId`. When provided, Appwrite stages the bulk request and applies it on commit. See [Transactions](/docs/products/databases/vectorsdb/transactions). + +{% multicode %} +```server-nodejs +await vectorsDB.upsertDocuments({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documents: [ + { $id: sdk.ID.unique(), embeddings: [0.12, 0.84, 0.33, 0.57], metadata: { title: 'One' } }, + { $id: sdk.ID.unique(), embeddings: [0.91, 0.22, 0.14, 0.65], metadata: { title: 'Two' } } + ], + transactionId: '<TRANSACTION_ID>' +}); +``` +```python +vectors_db.upsert_documents( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>', + documents = [ + { '$id': ID.unique(), 'embeddings': [0.12, 0.84, 0.33, 0.57], 'metadata': { 'title': 'One' } }, + { '$id': ID.unique(), 'embeddings': [0.91, 0.22, 0.14, 0.65], 'metadata': { 'title': 'Two' } } + ], + transaction_id = '<TRANSACTION_ID>' +) +``` +```server-rust +let result = vectors_db.upsert_documents( + "<DATABASE_ID>", + "<COLLECTION_ID>", + vec![ + json!({ + "$id": ID::unique(), + "embeddings": [0.12, 0.84, 0.33, 0.57], + "metadata": { "title": "One" } + }), + json!({ + "$id": ID::unique(), + "embeddings": [0.91, 0.22, 0.14, 0.65], + "metadata": { "title": "Two" } + }), + ], + Some("<TRANSACTION_ID>"), +).await?; +``` +{% /multicode %} diff --git a/src/routes/docs/products/databases/vectorsdb/collections/+page.markdoc b/src/routes/docs/products/databases/vectorsdb/collections/+page.markdoc new file mode 100644 index 00000000000..bf246bde573 --- /dev/null +++ b/src/routes/docs/products/databases/vectorsdb/collections/+page.markdoc @@ -0,0 +1,1144 @@ +--- +layout: article +title: Collections +description: Organize embeddings with Appwrite VectorsDB collections. Learn how to create collections with a fixed dimension, manage them, and configure permissions. +--- +Appwrite uses collections as containers of documents. +A VectorsDB collection stores embeddings, so every collection is created with a fixed **`dimension`**, the length of the embedding vectors it holds. All documents in the collection must use vectors of that exact length. + +Unlike TablesDB, you don't define a schema for a VectorsDB collection. The schema is fixed and provisioned for you when the collection is created: + +| Attribute | Type | Description | +|--------------|----------|-----------------------------------------------------------------------------| +| `embeddings` | `vector` | The embedding vector. Required, and sized to the collection's `dimension`. | +| `metadata` | `object` | Arbitrary JSON stored alongside the vector. Optional. | + +Because the schema is fixed, VectorsDB has no typed-attribute endpoints like TablesDB columns. You cannot add, update, or delete attributes on a collection. You store your vector under `embeddings` and any associated data under `metadata`. + +# Create collection {% #create-collection %} +You can create collections using the Appwrite Console, a [Server SDK](/docs/sdks#server), or using the [CLI](/docs/tooling/command-line/installation). + +Head to the **Databases** page, open a [database](/docs/products/databases/vectorsdb/databases), and click **Create collection**. Set a **dimension** that matches the embedding model you plan to use. + +You can also create collections programmatically using a [Server SDK](/docs/sdks#server). Appwrite [Server SDKs](/docs/sdks#server) require an [API key](/docs/advanced/platform/api-keys). + +The `dimension` is required and must match the length of the vectors you'll store. For example, the default `nomic-embed-text` model produces 768-dimensional vectors, so you would create the collection with `dimension: 768`. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.createCollection({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + name: '<NAME>', + dimension: 768, + permissions: [sdk.Permission.read(sdk.Role.any())], // optional + documentSecurity: false, // optional + enabled: true // optional +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.createCollection({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + name: '<NAME>', + dimension: 768, + permissions: [sdk.Permission.read(sdk.Role.any())], // optional + documentSecurity: false, // optional + enabled: true // optional +}); +``` +```php +<?php + +use Appwrite\Client; +use Appwrite\Services\VectorsDB; +use Appwrite\Permission; +use Appwrite\Role; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('<YOUR_PROJECT_ID>') // Your project ID + ->setKey('<YOUR_API_KEY>'); // Your secret API key + +$vectorsDB = new VectorsDB($client); + +$result = $vectorsDB->createCollection( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + name: '<NAME>', + dimension: 768, + permissions: [Permission::read(Role::any())], // optional + documentSecurity: false, // optional + enabled: true // optional +); +``` +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB +from appwrite.permission import Permission +from appwrite.role import Role + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('<YOUR_PROJECT_ID>') # Your project ID +client.set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB(client) + +result = vectors_db.create_collection( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>', + name = '<NAME>', + dimension = 768, + permissions = [Permission.read(Role.any())], # optional + document_security = False, # optional + enabled = True # optional +) +``` +```ruby +require 'appwrite' + +include Appwrite +include Appwrite::Permission +include Appwrite::Role + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('<YOUR_PROJECT_ID>') # Your project ID + .set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB.new(client) + +result = vectors_db.create_collection( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + name: '<NAME>', + dimension: 768, + permissions: [Permission.read(Role.any())], # optional + document_security: false, # optional + enabled: true # optional +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("<YOUR_PROJECT_ID>") // Your project ID + .SetKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +Collection result = await vectorsDB.CreateCollection( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + name: "<NAME>", + dimension: 768, + permissions: new List<string> { Permission.Read(Role.Any()) }, // optional + documentSecurity: false, // optional + enabled: true // optional +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; +import 'package:dart_appwrite/permission.dart'; +import 'package:dart_appwrite/role.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +VectorsDB vectorsDB = VectorsDB(client); + +Collection result = await vectorsDB.createCollection( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + name: '<NAME>', + dimension: 768, + permissions: [Permission.read(Role.any())], // (optional) + documentSecurity: false, // (optional) + enabled: true, // (optional) +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.Permission +import io.appwrite.Role +import io.appwrite.services.VectorsDB + +val client = Client(context) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +val vectorsDB = VectorsDB(client) + +val response = vectorsDB.createCollection( + databaseId = "<DATABASE_ID>", + collectionId = "<COLLECTION_ID>", + name = "<NAME>", + dimension = 768, + permissions = listOf(Permission.read(Role.any())), // optional + documentSecurity = false, // optional + enabled = true, // optional +) +``` +```java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.VectorsDB; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +vectorsDB.createCollection( + "<DATABASE_ID>", + "<COLLECTION_ID>", + "<NAME>", + 768, + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +let vectorsDB = VectorsDB(client) + +let collection = try await vectorsDB.createCollection( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + name: "<NAME>", + dimension: 768, + permissions: [Permission.read(Role.any())], // optional + documentSecurity: false, // optional + enabled: true // optional +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::VectorsDB; +use appwrite::permission::Permission; +use appwrite::role::Role; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.create_collection( + "<DATABASE_ID>", + "<COLLECTION_ID>", + "<NAME>", + 768, + Some(vec![Permission::read(Role::any()).to_string()]), // permissions (optional) + Some(false), // documentSecurity (optional) + Some(true), // enabled (optional) + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite vectors-db create-collection \ + --database-id "<DATABASE_ID>" \ + --collection-id "<COLLECTION_ID>" \ + --name "<NAME>" \ + --dimension 768 +``` +{% /multicode %} + +{% info title="Dimension is fixed" %} +The `dimension` is set when the collection is created and applies to every document in it. Choose a value that matches your embedding model, between 1 and 16000. To store vectors of a different length, create a separate collection. +{% /info %} + +# Schema {% #schema %} +A VectorsDB collection's schema is provisioned automatically and cannot be changed. Every collection has exactly two attributes: + +- `embeddings`, a required `vector` attribute sized to the collection's `dimension`. +- `metadata`, an optional `object` attribute that holds arbitrary JSON. + +A document's `data` therefore looks like this, where the vector length equals the collection's `dimension`: + +```json +{ + "embeddings": [0.12, 0.84, 0.05, 0.63], + "metadata": { "title": "Introduction", "source": "docs" } +} +``` + +An `object` index on `metadata` is also created for you. There are no endpoints to add, modify, or remove attributes. To learn how to write and read this data, see [Documents](/docs/products/databases/vectorsdb/documents). + +# Manage collections {% #manage-collections %} +Use a [Server SDK](/docs/sdks#server) to list, retrieve, update, and delete collections. + +## List collections {% #list-collections %} +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.listCollections({ + databaseId: '<DATABASE_ID>' +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.listCollections({ + databaseId: '<DATABASE_ID>' +}); +``` +```php +<?php + +use Appwrite\Client; +use Appwrite\Services\VectorsDB; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('<YOUR_PROJECT_ID>') // Your project ID + ->setKey('<YOUR_API_KEY>'); // Your secret API key + +$vectorsDB = new VectorsDB($client); + +$result = $vectorsDB->listCollections( + databaseId: '<DATABASE_ID>' +); +``` +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('<YOUR_PROJECT_ID>') # Your project ID +client.set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB(client) + +result = vectors_db.list_collections( + database_id = '<DATABASE_ID>' +) +``` +```ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('<YOUR_PROJECT_ID>') # Your project ID + .set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB.new(client) + +result = vectors_db.list_collections( + database_id: '<DATABASE_ID>' +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("<YOUR_PROJECT_ID>") // Your project ID + .SetKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +CollectionList result = await vectorsDB.ListCollections( + databaseId: "<DATABASE_ID>" +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +VectorsDB vectorsDB = VectorsDB(client); + +CollectionList result = await vectorsDB.listCollections( + databaseId: '<DATABASE_ID>', +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.services.VectorsDB + +val client = Client(context) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +val vectorsDB = VectorsDB(client) + +val response = vectorsDB.listCollections( + databaseId = "<DATABASE_ID>", +) +``` +```java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.VectorsDB; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +vectorsDB.listCollections( + "<DATABASE_ID>", + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +let vectorsDB = VectorsDB(client) + +let collectionList = try await vectorsDB.listCollections( + databaseId: "<DATABASE_ID>" +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::VectorsDB; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.list_collections( + "<DATABASE_ID>", + None, // queries (optional) + None, // search (optional) + None, // total (optional) + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite vectors-db list-collections \ + --database-id "<DATABASE_ID>" +``` +{% /multicode %} + +## Get collection {% #get-collection %} +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.getCollection({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>' +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.getCollection({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>' +}); +``` +```php +<?php + +use Appwrite\Client; +use Appwrite\Services\VectorsDB; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('<YOUR_PROJECT_ID>') // Your project ID + ->setKey('<YOUR_API_KEY>'); // Your secret API key + +$vectorsDB = new VectorsDB($client); + +$result = $vectorsDB->getCollection( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>' +); +``` +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('<YOUR_PROJECT_ID>') # Your project ID +client.set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB(client) + +result = vectors_db.get_collection( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>' +) +``` +```ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('<YOUR_PROJECT_ID>') # Your project ID + .set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB.new(client) + +result = vectors_db.get_collection( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>' +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("<YOUR_PROJECT_ID>") // Your project ID + .SetKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +Collection result = await vectorsDB.GetCollection( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>" +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +VectorsDB vectorsDB = VectorsDB(client); + +Collection result = await vectorsDB.getCollection( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.services.VectorsDB + +val client = Client(context) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +val vectorsDB = VectorsDB(client) + +val response = vectorsDB.getCollection( + databaseId = "<DATABASE_ID>", + collectionId = "<COLLECTION_ID>", +) +``` +```java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.VectorsDB; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +vectorsDB.getCollection( + "<DATABASE_ID>", + "<COLLECTION_ID>", + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +let vectorsDB = VectorsDB(client) + +let collection = try await vectorsDB.getCollection( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>" +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::VectorsDB; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.get_collection( + "<DATABASE_ID>", + "<COLLECTION_ID>", + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite vectors-db get-collection \ + --database-id "<DATABASE_ID>" \ + --collection-id "<COLLECTION_ID>" +``` +{% /multicode %} + +## Update collection {% #update-collection %} +You can rename a collection and change its permissions, `documentSecurity`, or `enabled` state. The `name` is required when updating. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.updateCollection({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + name: '<NAME>', + documentSecurity: true // optional +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.updateCollection({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + name: '<NAME>', + documentSecurity: true // optional +}); +``` +```php +<?php + +use Appwrite\Client; +use Appwrite\Services\VectorsDB; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('<YOUR_PROJECT_ID>') // Your project ID + ->setKey('<YOUR_API_KEY>'); // Your secret API key + +$vectorsDB = new VectorsDB($client); + +$result = $vectorsDB->updateCollection( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + name: '<NAME>', + documentSecurity: true // optional +); +``` +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('<YOUR_PROJECT_ID>') # Your project ID +client.set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB(client) + +result = vectors_db.update_collection( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>', + name = '<NAME>', + document_security = True # optional +) +``` +```ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('<YOUR_PROJECT_ID>') # Your project ID + .set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB.new(client) + +result = vectors_db.update_collection( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + name: '<NAME>', + document_security: true # optional +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("<YOUR_PROJECT_ID>") // Your project ID + .SetKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +Collection result = await vectorsDB.UpdateCollection( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + name: "<NAME>", + documentSecurity: true // optional +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +VectorsDB vectorsDB = VectorsDB(client); + +Collection result = await vectorsDB.updateCollection( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + name: '<NAME>', + documentSecurity: true, // (optional) +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.services.VectorsDB + +val client = Client(context) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +val vectorsDB = VectorsDB(client) + +val response = vectorsDB.updateCollection( + databaseId = "<DATABASE_ID>", + collectionId = "<COLLECTION_ID>", + name = "<NAME>", + documentSecurity = true, // optional +) +``` +```java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.VectorsDB; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +vectorsDB.updateCollection( + "<DATABASE_ID>", + "<COLLECTION_ID>", + "<NAME>", + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +let vectorsDB = VectorsDB(client) + +let collection = try await vectorsDB.updateCollection( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + name: "<NAME>", + documentSecurity: true // optional +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::VectorsDB; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.update_collection( + "<DATABASE_ID>", + "<COLLECTION_ID>", + "<NAME>", + None, // dimension (optional) + None, // permissions (optional) + Some(true), // documentSecurity (optional) + None, // enabled (optional) + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite vectors-db update-collection \ + --database-id "<DATABASE_ID>" \ + --collection-id "<COLLECTION_ID>" \ + --name "<NAME>" +``` +{% /multicode %} + +## Delete collection {% #delete-collection %} +Deleting a collection permanently removes it and all of its documents. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.deleteCollection({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>' +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.deleteCollection({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>' +}); +``` +```php +<?php + +use Appwrite\Client; +use Appwrite\Services\VectorsDB; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('<YOUR_PROJECT_ID>') // Your project ID + ->setKey('<YOUR_API_KEY>'); // Your secret API key + +$vectorsDB = new VectorsDB($client); + +$result = $vectorsDB->deleteCollection( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>' +); +``` +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('<YOUR_PROJECT_ID>') # Your project ID +client.set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB(client) + +result = vectors_db.delete_collection( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>' +) +``` +```ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('<YOUR_PROJECT_ID>') # Your project ID + .set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB.new(client) + +result = vectors_db.delete_collection( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>' +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("<YOUR_PROJECT_ID>") // Your project ID + .SetKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +await vectorsDB.DeleteCollection( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>" +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +VectorsDB vectorsDB = VectorsDB(client); + +await vectorsDB.deleteCollection( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.services.VectorsDB + +val client = Client(context) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +val vectorsDB = VectorsDB(client) + +vectorsDB.deleteCollection( + databaseId = "<DATABASE_ID>", + collectionId = "<COLLECTION_ID>", +) +``` +```java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.VectorsDB; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +vectorsDB.deleteCollection( + "<DATABASE_ID>", + "<COLLECTION_ID>", + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +let vectorsDB = VectorsDB(client) + +try await vectorsDB.deleteCollection( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>" +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::VectorsDB; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + vectors_db.delete_collection( + "<DATABASE_ID>", + "<COLLECTION_ID>", + ).await?; + + Ok(()) +} +``` +```bash +appwrite vectors-db delete-collection \ + --database-id "<DATABASE_ID>" \ + --collection-id "<COLLECTION_ID>" +``` +{% /multicode %} + +# Permissions {% #permissions %} +Appwrite uses permissions to control data access. +For security, only users that are granted permissions can access a resource. + +By default, Appwrite doesn't grant permissions to any users when a new collection is created. +This means users can't create documents or read, update, and delete existing documents until you grant access. + +Set `documentSecurity` to `true` on a collection to configure permissions on individual documents. A user then needs either collection level or document level permissions to access a document. + +[Learn about configuring permissions](/docs/products/databases/vectorsdb/permissions). diff --git a/src/routes/docs/products/databases/vectorsdb/csv-exports/+page.markdoc b/src/routes/docs/products/databases/vectorsdb/csv-exports/+page.markdoc new file mode 100644 index 00000000000..c80841bc888 --- /dev/null +++ b/src/routes/docs/products/databases/vectorsdb/csv-exports/+page.markdoc @@ -0,0 +1,102 @@ +--- +layout: article +title: CSV exports +description: Export VectorsDB documents to a CSV file. Share embeddings and metadata as a portable dataset without writing custom scripts. +--- + +Appwrite's CSV export feature lets you export documents from a VectorsDB collection to a CSV file. This is useful for reporting, sharing a dataset with your team, creating custom backups, or handing embeddings and their metadata off to other tools. + +# Exported columns {% #exported-columns %} + +A VectorsDB collection has a fixed schema, so every export has the same shape. Each row carries the document's system fields together with the two collection attributes: + +| Column | Type | Description | +|--------------|--------|--------------------------------------------------------------------------| +| `$id` | string | The document ID. | +| `embeddings` | JSON | The embedding vector, serialized as a JSON array of numbers. | +| `metadata` | JSON | The metadata stored alongside the vector, serialized as a JSON object. | + +System columns like `$id`, `$createdAt`, and `$updatedAt` are included automatically. Because `embeddings` is the full vector for each document, exported files can be large for high dimension collections. + +An example of exported data, where each `embeddings` value is the full vector for that document: + +```text +$id,embeddings,metadata +doc-1,"[0.12,0.84,0.33,0.57]","{""title"":""Hamlet"",""year"":1601}" +doc-2,"[0.2,0.1,0.6,0.1]","{""title"":""Macbeth"",""year"":1606}" +doc-3,"[0.5,0.5,0.5,0.5]","{""title"":""Othello"",""year"":1603}" +``` + +# Export configuration {% #export-configuration %} + +Before exporting, you can configure several options to control the output format and contents. + +## Apply filters {% #apply-filters %} + +You can pass [queries](/docs/products/databases/vectorsdb/queries) to export only the documents you need rather than the whole collection. This is useful when you want a subset of your data for a specific use case. + +## Select columns {% #select-columns %} + +You can choose which columns to include in the export. By default, all columns are exported. Selecting specific columns creates more focused datasets, for example exporting only `metadata` when you don't need the raw vectors. + +## Custom delimiter {% #custom-delimiter %} + +You can set a custom delimiter for the CSV file. While commas are standard, you can use tabs, semicolons, or other delimiters based on the tools you import into. + +Common delimiters: +- **Comma (`,`)**: Standard format, compatible with most tools +- **Tab**: Useful when your data contains many commas +- **Semicolon (`;`)**: Common in European Excel versions +- **Pipe (`|`)**: Useful when your data contains many semicolons + +## Header row {% #header-row %} + +You can choose whether to include a header row with column names. Headers make the data easier to read in spreadsheets, but some import tools work better without them. + +# Timestamps {% #timestamps %} + +The `$createdAt` and `$updatedAt` columns are exported in ISO 8601 format, making them compatible with most spreadsheet and database tools. + +# Permissions {% #permissions %} + +If [document security](/docs/products/databases/vectorsdb/permissions) is enabled for your collection, the `$permissions` column is included in the export. Permission strings are formatted as comma-separated role definitions within quotes. + +```text +$id,embeddings,$permissions +doc-1,"[0.12,0.84,0.33,0.57]","read(""any""),update(""user:user-123"")" +doc-2,"[0.2,0.1,0.6,0.1]","read(""team:team-456""),update(""team:team-456"")" +``` + +The roles used are API strings that can be found in the [permissions documentation](/docs/products/databases/vectorsdb/permissions). + +# Background processing {% #background-processing %} + +Large exports run as background tasks so they don't block your workflow. When an export completes, you receive an email with a short-lived download link to retrieve your CSV file. + +This means you can start an export, close the Console, and return later to download your file. The Console displays a floating progress bar while the export is active. + +# Use cases {% #use-cases %} + +CSV exports are useful for many common workflows: + +- **Reporting**: Generate reports for stakeholders who need data in spreadsheet format +- **Data sharing**: Share an embeddings dataset with teammates +- **Analytics hand-off**: Provide vectors and metadata to analysts using other tools +- **Custom backups**: Archive specific data subsets for record-keeping +- **Migration preparation**: Extract data to move it into another system + +# Best practices {% #best-practices %} + +To get the most out of CSV exports: + +1. **Filter your data**: Export only the documents you need to reduce file size and processing time +2. **Select specific columns**: Export only `metadata` when you don't need the raw vectors, since high dimension `embeddings` columns make files much larger +3. **Choose appropriate delimiters**: Use tabs or semicolons if your data contains many commas +4. **Consider header requirements**: Include headers for human readability, exclude them for automated imports + +# Additional resources {% #additional-resources %} + +- [CSV imports](/docs/products/databases/vectorsdb/csv-imports) - Import data from CSV files +- [Documents](/docs/products/databases/vectorsdb/documents) - Create, read, update, and delete documents +- [Permissions](/docs/products/databases/vectorsdb/permissions) - Configure document-level security +- [Backups](/docs/products/databases/vectorsdb/backups) - Automated backup policies diff --git a/src/routes/docs/products/databases/vectorsdb/csv-imports/+page.markdoc b/src/routes/docs/products/databases/vectorsdb/csv-imports/+page.markdoc new file mode 100644 index 00000000000..6e94bf6e5d4 --- /dev/null +++ b/src/routes/docs/products/databases/vectorsdb/csv-imports/+page.markdoc @@ -0,0 +1,118 @@ +--- +layout: article +title: CSV imports +description: Import embeddings into Appwrite VectorsDB by uploading a CSV file. Learn how to format the embeddings and metadata columns for a bulk import. +--- + +Appwrite's CSV Import feature allows you to create multiple documents in a collection by uploading a single CSV file. This is especially useful for loading precomputed embeddings, seeding test environments, or migrating vectors from another system. + +# Prepare your CSV {% #prepare-csv %} + +A VectorsDB collection has a fixed schema, so every CSV maps to the same two columns: + +| Column | Type | Description | +|--------------|----------|----------------------------------------------------------------------------------| +| `embeddings` | `vector` | The embedding vector, written as a JSON array. Required, and its length must equal the collection's `dimension`. | +| `metadata` | `object` | Arbitrary JSON stored alongside the vector, written as a JSON object. Optional. | + +Each row represents a new document. The `embeddings` value is parsed as a JSON array of numbers, and the `metadata` value is parsed as a JSON object. Each row is validated before being imported. + +{% info title="Good to know" %} +You can optionally include the `$id` column to define custom document IDs. If not provided, Appwrite will generate unique IDs for each document automatically. + +Appwrite imports documents in batches of 100 documents at a time. If a provided ID already exists in the collection, the entire batch containing that document will fail, but documents in other batches will continue to be imported successfully. +{% /info %} + +An example of a valid CSV file for a collection created with `dimension: 4`: + +```text +$id,embeddings,metadata +vec_1,"[0.12,0.04,0.88,0.31]","{""title"":""First vector"",""year"":2024}" +vec_2,"[0.55,0.61,0.07,0.42]","{""title"":""Second vector"",""year"":2025}" +vec_3,"[0.20,0.20,0.20,0.20]","{""title"":""Third vector"",""year"":2025}" +``` + +The double quotes around each value let you include the commas inside the JSON array and object. The inner double quotes of the JSON keys and string values are escaped by doubling them (`""`). See [Special characters](#special-characters) for the escaping rules. + +{% info title="Vector length" %} +Every `embeddings` array must contain exactly as many numbers as the collection's `dimension`. A row whose vector length does not match the dimension is rejected. +{% /info %} + +# Metadata values {% #metadata-values %} + +The `metadata` column is an object, so each value must be a valid JSON object or the literal `null`: + +- **A JSON object**, for example `"{""key"":""value""}"`. An empty object `"{}"` is also valid. +- **`null`** (the unquoted literal) stores no metadata for that document. + +A blank `metadata` value is not accepted. To omit metadata for a row, use `null` rather than leaving the field empty: + +```text +$id,embeddings,metadata +vec_1,"[0.12,0.04,0.88,0.31]","{""title"":""With metadata""}" +vec_2,"[0.55,0.61,0.07,0.42]",null +``` + +# Create and update timestamps {% #created-at-and-updated-at %} + +You can also optionally include `$createdAt` and `$updatedAt` columns to set custom timestamps for imported documents. If omitted, Appwrite sets these automatically during import. + +An example of a valid CSV file with `$createdAt` and `$updatedAt` timestamps: + +```text +$id,$createdAt,$updatedAt,embeddings,metadata +vec_1,2025-08-10T12:34:56.000Z,2025-08-10T12:34:56.000Z,"[0.12,0.04,0.88,0.31]","{""title"":""First vector""}" +vec_2,2025-08-11T09:15:00.000Z,2025-08-11T10:00:00.000Z,"[0.55,0.61,0.07,0.42]","{""title"":""Second vector""}" +``` + +{% info title="Timestamps format" %} +`$createdAt` and `$updatedAt` must be valid ISO 8601 date-time strings, for example: `2025-08-10T12:34:56.000Z`. +{% /info %} + +# Permissions {% #permissions %} + +You can set permissions for documents in your CSV file by adding data for the `$permissions` column. Make sure document level security is enabled for your collection. + +An example of a valid permissions string: + +```text +"read(""any""),update(""users""),delete(""user:user_id"")" +``` + +The roles used are API strings that can be found in the [permissions documentation](/docs/apis/rest#roles). + +A full example of a valid CSV file with document permissions: + +```text +$id,embeddings,metadata,$permissions +vec_1,"[0.12,0.04,0.88,0.31]","{""title"":""First vector""}","read(""any""),update(""user:user_id""),delete(""user:user_id"")" +vec_2,"[0.55,0.61,0.07,0.42]","{""title"":""Second vector""}","read(""users""),update(""user:user_id"")" +``` + +# Special characters {% #special-characters %} + +The `embeddings` and `metadata` values are JSON written inside CSV fields, so you need to escape the characters that CSV treats specially. + +## Comma + +The JSON array and object both contain commas, so wrap each value in double quotes (`"[0.1,0.2,0.3,0.4]"`). Without the surrounding quotes, the commas would be read as column separators. + +## Double quotes + +JSON keys and string values use double quotes, and a double quote inside a quoted CSV field must be escaped by doubling it (`""`). For example, the object `{"title":"hello"}` is written in the CSV as `"{""title"":""hello""}"`. + +# Run the import {% #run-import %} + +CSV imports run as a background migration. First upload your CSV to a [storage bucket](/docs/products/storage/buckets), then start the import against the target collection. The import is triggered through the migrations endpoint at `POST /v1/migrations/csv/imports` with an [API key](/docs/advanced/platform/api-keys) that has the `migrations.write` scope. The request takes the storage `bucketId` and `fileId` that hold your CSV, and the target collection as a composite `resourceId` in the form `databaseId:collectionId`. + +The `onDuplicate` option controls what happens when a document with an existing `$id` is encountered: `fail` (the default) aborts on the first conflict, `skip` ignores it, and `overwrite` replaces the existing document. + +{% info title="Console import" %} +The VectorsDB collection view in the Appwrite Console offers JSON import and export. To import a CSV into a VectorsDB collection, use the migrations endpoint described above. +{% /info %} + +# Additional resources {% #additional-resources %} + +- [Appwrite CLI](/docs/command-line) +- [Database permissions](/docs/products/databases/vectorsdb/permissions) +- [Embeddings](/docs/products/databases/vectorsdb/embeddings) diff --git a/src/routes/docs/products/databases/vectorsdb/databases/+page.markdoc b/src/routes/docs/products/databases/vectorsdb/databases/+page.markdoc new file mode 100644 index 00000000000..7802e672768 --- /dev/null +++ b/src/routes/docs/products/databases/vectorsdb/databases/+page.markdoc @@ -0,0 +1,975 @@ +--- +layout: article +title: Databases +description: Dive deeper into Appwrite VectorsDB and database configuration. Learn how to create and manage multiple vector databases for your application. +--- +Databases are the largest organizational unit in Appwrite. +Each database contains a group of [collections](/docs/products/databases/vectorsdb/collections). + +# Shared and dedicated databases {% #shared-and-dedicated %} +VectorsDB databases run on either shared or dedicated infrastructure. + +Shared databases run on infrastructure that Appwrite manages and scales for you. They are the fastest way to get started and you can create them from the Console or programmatically with a [Server SDK](/docs/sdks#server). + +Dedicated databases run on infrastructure provisioned for your project alone. They can only be created from the Appwrite Console. Once created, you manage their collections and documents with the same SDK methods as a shared database. + +# Create in Console {% #create-in-console %} +The easiest way to create a database is using the Appwrite Console. +Navigate to the **Databases** page and click **Create database**, choose **VectorsDB** as the database type, and select your preferred tier. + +# Create using Server SDKs {% #create-using-server-sdks %} +You can programmatically create a shared database using a [Server SDK](/docs/sdks#server). Appwrite [Server SDKs](/docs/sdks#server) require an [API key](/docs/advanced/platform/api-keys). + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.create({ + databaseId: '<DATABASE_ID>', + name: '<NAME>' +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.create({ + databaseId: '<DATABASE_ID>', + name: '<NAME>' +}); +``` +```php +<?php + +use Appwrite\Client; +use Appwrite\Services\VectorsDB; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('<YOUR_PROJECT_ID>') // Your project ID + ->setKey('<YOUR_API_KEY>'); // Your secret API key + +$vectorsDB = new VectorsDB($client); + +$result = $vectorsDB->create( + databaseId: '<DATABASE_ID>', + name: '<NAME>' +); +``` +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('<YOUR_PROJECT_ID>') # Your project ID +client.set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB(client) + +result = vectors_db.create( + database_id = '<DATABASE_ID>', + name = '<NAME>' +) +``` +```ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('<YOUR_PROJECT_ID>') # Your project ID + .set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB.new(client) + +result = vectors_db.create( + database_id: '<DATABASE_ID>', + name: '<NAME>' +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("<YOUR_PROJECT_ID>") // Your project ID + .SetKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +Database result = await vectorsDB.Create( + databaseId: "<DATABASE_ID>", + name: "<NAME>" +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +VectorsDB vectorsDB = VectorsDB(client); + +Database result = await vectorsDB.create( + databaseId: '<DATABASE_ID>', + name: '<NAME>', +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.services.VectorsDB + +val client = Client(context) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +val vectorsDB = VectorsDB(client) + +val response = vectorsDB.create( + databaseId = "<DATABASE_ID>", + name = "<NAME>", +) +``` +```java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.VectorsDB; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +vectorsDB.create( + "<DATABASE_ID>", + "<NAME>", + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +let vectorsDB = VectorsDB(client) + +let database = try await vectorsDB.create( + databaseId: "<DATABASE_ID>", + name: "<NAME>" +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.create( + "<DATABASE_ID>", + "<NAME>", + None, // enabled (optional) + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite vectors-db create \ + --database-id <DATABASE_ID> \ + --name <NAME> +``` +{% /multicode %} + +# List databases {% #list-databases %} +Use the `list` method to retrieve all databases in your project. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.list({}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.list({}); +``` +```php +<?php + +use Appwrite\Client; +use Appwrite\Services\VectorsDB; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('<YOUR_PROJECT_ID>') // Your project ID + ->setKey('<YOUR_API_KEY>'); // Your secret API key + +$vectorsDB = new VectorsDB($client); + +$result = $vectorsDB->list(); +``` +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('<YOUR_PROJECT_ID>') # Your project ID +client.set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB(client) + +result = vectors_db.list() +``` +```ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('<YOUR_PROJECT_ID>') # Your project ID + .set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB.new(client) + +result = vectors_db.list() +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("<YOUR_PROJECT_ID>") // Your project ID + .SetKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +DatabaseList result = await vectorsDB.List(); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +VectorsDB vectorsDB = VectorsDB(client); + +DatabaseList result = await vectorsDB.list(); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.services.VectorsDB + +val client = Client(context) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +val vectorsDB = VectorsDB(client) + +val response = vectorsDB.list() +``` +```java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.VectorsDB; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +vectorsDB.list( + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +let vectorsDB = VectorsDB(client) + +let databaseList = try await vectorsDB.list() +``` +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.list( + None, // queries (optional) + None, // search (optional) + None, // total (optional) + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite vectors-db list +``` +{% /multicode %} + +# Get a database {% #get-database %} +Use the `get` method to retrieve a single database by its ID. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.get({ + databaseId: '<DATABASE_ID>' +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.get({ + databaseId: '<DATABASE_ID>' +}); +``` +```php +<?php + +use Appwrite\Client; +use Appwrite\Services\VectorsDB; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('<YOUR_PROJECT_ID>') // Your project ID + ->setKey('<YOUR_API_KEY>'); // Your secret API key + +$vectorsDB = new VectorsDB($client); + +$result = $vectorsDB->get( + databaseId: '<DATABASE_ID>' +); +``` +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('<YOUR_PROJECT_ID>') # Your project ID +client.set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB(client) + +result = vectors_db.get( + database_id = '<DATABASE_ID>' +) +``` +```ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('<YOUR_PROJECT_ID>') # Your project ID + .set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB.new(client) + +result = vectors_db.get( + database_id: '<DATABASE_ID>' +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("<YOUR_PROJECT_ID>") // Your project ID + .SetKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +Database result = await vectorsDB.Get( + databaseId: "<DATABASE_ID>" +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +VectorsDB vectorsDB = VectorsDB(client); + +Database result = await vectorsDB.get( + databaseId: '<DATABASE_ID>', +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.services.VectorsDB + +val client = Client(context) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +val vectorsDB = VectorsDB(client) + +val response = vectorsDB.get( + databaseId = "<DATABASE_ID>", +) +``` +```java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.VectorsDB; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +vectorsDB.get( + "<DATABASE_ID>", + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +let vectorsDB = VectorsDB(client) + +let database = try await vectorsDB.get( + databaseId: "<DATABASE_ID>" +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.get( + "<DATABASE_ID>", + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite vectors-db get \ + --database-id <DATABASE_ID> +``` +{% /multicode %} + +# Update a database {% #update-database %} +Use the `update` method to change a database's name or enabled state. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.update({ + databaseId: '<DATABASE_ID>', + name: '<NAME>' +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.update({ + databaseId: '<DATABASE_ID>', + name: '<NAME>' +}); +``` +```php +<?php + +use Appwrite\Client; +use Appwrite\Services\VectorsDB; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('<YOUR_PROJECT_ID>') // Your project ID + ->setKey('<YOUR_API_KEY>'); // Your secret API key + +$vectorsDB = new VectorsDB($client); + +$result = $vectorsDB->update( + databaseId: '<DATABASE_ID>', + name: '<NAME>' +); +``` +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('<YOUR_PROJECT_ID>') # Your project ID +client.set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB(client) + +result = vectors_db.update( + database_id = '<DATABASE_ID>', + name = '<NAME>' +) +``` +```ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('<YOUR_PROJECT_ID>') # Your project ID + .set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB.new(client) + +result = vectors_db.update( + database_id: '<DATABASE_ID>', + name: '<NAME>' +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("<YOUR_PROJECT_ID>") // Your project ID + .SetKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +Database result = await vectorsDB.Update( + databaseId: "<DATABASE_ID>", + name: "<NAME>" +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +VectorsDB vectorsDB = VectorsDB(client); + +Database result = await vectorsDB.update( + databaseId: '<DATABASE_ID>', + name: '<NAME>', +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.services.VectorsDB + +val client = Client(context) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +val vectorsDB = VectorsDB(client) + +val response = vectorsDB.update( + databaseId = "<DATABASE_ID>", + name = "<NAME>", +) +``` +```java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.VectorsDB; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +vectorsDB.update( + "<DATABASE_ID>", + "<NAME>", + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +let vectorsDB = VectorsDB(client) + +let database = try await vectorsDB.update( + databaseId: "<DATABASE_ID>", + name: "<NAME>" +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.update( + "<DATABASE_ID>", + "<NAME>", + None, // enabled (optional) + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite vectors-db update \ + --database-id <DATABASE_ID> \ + --name <NAME> +``` +{% /multicode %} + +# Delete a database {% #delete-database %} +Use the `delete` method to permanently remove a database and all of its collections and documents. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.delete({ + databaseId: '<DATABASE_ID>' +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.delete({ + databaseId: '<DATABASE_ID>' +}); +``` +```php +<?php + +use Appwrite\Client; +use Appwrite\Services\VectorsDB; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('<YOUR_PROJECT_ID>') // Your project ID + ->setKey('<YOUR_API_KEY>'); // Your secret API key + +$vectorsDB = new VectorsDB($client); + +$result = $vectorsDB->delete( + databaseId: '<DATABASE_ID>' +); +``` +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('<YOUR_PROJECT_ID>') # Your project ID +client.set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB(client) + +result = vectors_db.delete( + database_id = '<DATABASE_ID>' +) +``` +```ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('<YOUR_PROJECT_ID>') # Your project ID + .set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB.new(client) + +result = vectors_db.delete( + database_id: '<DATABASE_ID>' +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("<YOUR_PROJECT_ID>") // Your project ID + .SetKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +await vectorsDB.Delete( + databaseId: "<DATABASE_ID>" +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +VectorsDB vectorsDB = VectorsDB(client); + +await vectorsDB.delete( + databaseId: '<DATABASE_ID>', +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.services.VectorsDB + +val client = Client(context) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +val vectorsDB = VectorsDB(client) + +vectorsDB.delete( + databaseId = "<DATABASE_ID>", +) +``` +```java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.VectorsDB; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +vectorsDB.delete( + "<DATABASE_ID>", + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +let vectorsDB = VectorsDB(client) + +try await vectorsDB.delete( + databaseId: "<DATABASE_ID>" +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + vectors_db.delete( + "<DATABASE_ID>", + ).await?; + + Ok(()) +} +``` +```bash +appwrite vectors-db delete \ + --database-id <DATABASE_ID> +``` +{% /multicode %} diff --git a/src/routes/docs/products/databases/vectorsdb/documents/+page.markdoc b/src/routes/docs/products/databases/vectorsdb/documents/+page.markdoc new file mode 100644 index 00000000000..ea820edce39 --- /dev/null +++ b/src/routes/docs/products/databases/vectorsdb/documents/+page.markdoc @@ -0,0 +1,1541 @@ +--- +layout: article +title: Documents +description: Create, read, update, and delete documents in Appwrite VectorsDB. Learn how to store embedding vectors and metadata in your collections. +--- +Each piece of data in Appwrite VectorsDB is a document. +A document's data follows the fixed schema provisioned by its collection: an `embeddings` vector and an optional `metadata` object. + +The `embeddings` array is required, and its length must equal the `dimension` you set when [creating the collection](/docs/products/databases/vectorsdb/collections). +The `metadata` field is free-form JSON, so you can attach any data you want to keep alongside each vector. + +{% info title="Embedding length must match the dimension" %} +If the `embeddings` array is longer or shorter than the collection's `dimension`, the request is rejected. +The examples on this page use a collection with `dimension: 4` to keep the arrays readable. +{% /info %} + +# Create documents {% #create-documents %} +{% info title="Permissions required" %} +You must grant _create_ permissions to users at the _collection level_ before users can create documents. +[Learn more about permissions](#permissions) +{% /info %} + +Use the `createDocument` method to add a document to a collection. Appwrite [Server SDKs](/docs/sdks#server) require an [API key](/docs/advanced/platform/api-keys). + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.createDocument({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: sdk.ID.unique(), + data: { + embeddings: [0.12, 0.84, 0.33, 0.57], + metadata: { title: 'Hamlet', year: 1601 } + }, + permissions: [sdk.Permission.read(sdk.Role.any())] // optional +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.createDocument({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: sdk.ID.unique(), + data: { + embeddings: [0.12, 0.84, 0.33, 0.57], + metadata: { title: 'Hamlet', year: 1601 } + }, + permissions: [sdk.Permission.read(sdk.Role.any())] // optional +}); +``` +```php +<?php + +use Appwrite\Client; +use Appwrite\Services\VectorsDB; +use Appwrite\ID; +use Appwrite\Permission; +use Appwrite\Role; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('<YOUR_PROJECT_ID>') // Your project ID + ->setKey('<YOUR_API_KEY>'); // Your secret API key + +$vectorsDB = new VectorsDB($client); + +$result = $vectorsDB->createDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: ID::unique(), + data: [ + 'embeddings' => [0.12, 0.84, 0.33, 0.57], + 'metadata' => ['title' => 'Hamlet', 'year' => 1601] + ], + permissions: [Permission::read(Role::any())] // optional +); +``` +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB +from appwrite.id import ID +from appwrite.permission import Permission +from appwrite.role import Role + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('<YOUR_PROJECT_ID>') # Your project ID +client.set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB(client) + +result = vectors_db.create_document( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>', + document_id = ID.unique(), + data = { + "embeddings": [0.12, 0.84, 0.33, 0.57], + "metadata": { "title": "Hamlet", "year": 1601 } + }, + permissions = [Permission.read(Role.any())] # optional +) +``` +```ruby +require 'appwrite' + +include Appwrite +include Appwrite::Permission +include Appwrite::Role + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('<YOUR_PROJECT_ID>') # Your project ID + .set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB.new(client) + +result = vectors_db.create_document( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + document_id: ID.unique(), + data: { + "embeddings" => [0.12, 0.84, 0.33, 0.57], + "metadata" => { "title" => "Hamlet", "year" => 1601 } + }, + permissions: [Permission.read(Role.any())] # optional +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("<YOUR_PROJECT_ID>") // Your project ID + .SetKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +Document result = await vectorsDB.CreateDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: ID.Unique(), + data: new Dictionary<string, object> { + { "embeddings", new List<double> { 0.12, 0.84, 0.33, 0.57 } }, + { "metadata", new Dictionary<string, object> { { "title", "Hamlet" }, { "year", 1601 } } } + }, + permissions: new List<string> { Permission.Read(Role.Any()) } // optional +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +VectorsDB vectorsDB = VectorsDB(client); + +Document result = await vectorsDB.createDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: ID.unique(), + data: { + "embeddings": [0.12, 0.84, 0.33, 0.57], + "metadata": { "title": "Hamlet", "year": 1601 } + }, + permissions: [Permission.read(Role.any())], // (optional) +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.ID +import io.appwrite.Permission +import io.appwrite.Role +import io.appwrite.services.VectorsDB + +val client = Client(context) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +val vectorsDB = VectorsDB(client) + +val response = vectorsDB.createDocument( + databaseId = "<DATABASE_ID>", + collectionId = "<COLLECTION_ID>", + documentId = ID.unique(), + data = mapOf( + "embeddings" to listOf(0.12, 0.84, 0.33, 0.57), + "metadata" to mapOf("title" to "Hamlet", "year" to 1601) + ), + permissions = listOf(Permission.read(Role.any())), // optional +) +``` +```java +import io.appwrite.Client; +import io.appwrite.ID; +import io.appwrite.Permission; +import io.appwrite.Role; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.VectorsDB; +import java.util.List; +import java.util.Map; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +vectorsDB.createDocument( + "<DATABASE_ID>", + "<COLLECTION_ID>", + ID.unique(), + Map.of( + "embeddings", List.of(0.12, 0.84, 0.33, 0.57), + "metadata", Map.of("title", "Hamlet", "year", 1601) + ), + List.of(Permission.read(Role.any())), + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +let vectorsDB = VectorsDB(client) + +let document = try await vectorsDB.createDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: ID.unique(), + data: [ + "embeddings": [0.12, 0.84, 0.33, 0.57], + "metadata": ["title": "Hamlet", "year": 1601] + ], + permissions: [Permission.read(Role.any())] // optional +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; +use appwrite::id::ID; +use appwrite::permission::Permission; +use appwrite::role::Role; +use serde_json::json; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.create_document( + "<DATABASE_ID>", + "<COLLECTION_ID>", + ID::unique(), + json!({ + "embeddings": [0.12, 0.84, 0.33, 0.57], + "metadata": { "title": "Hamlet", "year": 1601 } + }), + Some(vec![Permission::read(Role::any()).to_string()]), // optional + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite vectors-db create-document \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --document-id 'unique()' \ + --data '{ "embeddings": [0.12, 0.84, 0.33, 0.57], "metadata": { "title": "Hamlet", "year": 1601 } }' +``` +{% /multicode %} + +To insert many documents in a single request, use [bulk operations](/docs/products/databases/vectorsdb/bulk-operations) instead of calling `createDocument` in a loop. + +# Get document {% #get-document %} +Use the `getDocument` method to read a single document by its ID. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.getDocument({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>' +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.getDocument({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>' +}); +``` +```php +<?php + +use Appwrite\Client; +use Appwrite\Services\VectorsDB; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('<YOUR_PROJECT_ID>') // Your project ID + ->setKey('<YOUR_API_KEY>'); // Your secret API key + +$vectorsDB = new VectorsDB($client); + +$result = $vectorsDB->getDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>' +); +``` +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('<YOUR_PROJECT_ID>') # Your project ID +client.set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB(client) + +result = vectors_db.get_document( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>', + document_id = '<DOCUMENT_ID>' +) +``` +```ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('<YOUR_PROJECT_ID>') # Your project ID + .set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB.new(client) + +result = vectors_db.get_document( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + document_id: '<DOCUMENT_ID>' +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("<YOUR_PROJECT_ID>") // Your project ID + .SetKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +Document result = await vectorsDB.GetDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: "<DOCUMENT_ID>" +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +VectorsDB vectorsDB = VectorsDB(client); + +Document result = await vectorsDB.getDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.services.VectorsDB + +val client = Client(context) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +val vectorsDB = VectorsDB(client) + +val response = vectorsDB.getDocument( + databaseId = "<DATABASE_ID>", + collectionId = "<COLLECTION_ID>", + documentId = "<DOCUMENT_ID>", +) +``` +```java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.VectorsDB; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +vectorsDB.getDocument( + "<DATABASE_ID>", + "<COLLECTION_ID>", + "<DOCUMENT_ID>", + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +let vectorsDB = VectorsDB(client) + +let document = try await vectorsDB.getDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: "<DOCUMENT_ID>" +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.get_document( + "<DATABASE_ID>", + "<COLLECTION_ID>", + "<DOCUMENT_ID>", + None, // queries (optional) + None, // transactionId (optional) + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite vectors-db get-document \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --document-id <DOCUMENT_ID> +``` +{% /multicode %} + +# List documents {% #list-documents %} +Use the `listDocuments` method to read documents from a collection. Pass [queries](/docs/products/databases/vectorsdb/queries) to filter, order, and paginate the results. + +To rank documents by similarity to a query vector, use a vector search query instead. See [Vector search](/docs/products/databases/vectorsdb/vector-search). + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.listDocuments({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + sdk.Query.limit(10) + ] +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.listDocuments({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + sdk.Query.limit(10) + ] +}); +``` +```php +<?php + +use Appwrite\Client; +use Appwrite\Services\VectorsDB; +use Appwrite\Query; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('<YOUR_PROJECT_ID>') // Your project ID + ->setKey('<YOUR_API_KEY>'); // Your secret API key + +$vectorsDB = new VectorsDB($client); + +$result = $vectorsDB->listDocuments( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + Query::limit(10) + ] +); +``` +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB +from appwrite.query import Query + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('<YOUR_PROJECT_ID>') # Your project ID +client.set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB(client) + +result = vectors_db.list_documents( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>', + queries = [ + Query.limit(10) + ] +) +``` +```ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('<YOUR_PROJECT_ID>') # Your project ID + .set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB.new(client) + +result = vectors_db.list_documents( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + queries: [ + Query.limit(10) + ] +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("<YOUR_PROJECT_ID>") // Your project ID + .SetKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +DocumentList result = await vectorsDB.ListDocuments( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + queries: new List<string> { + Query.Limit(10) + } +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +VectorsDB vectorsDB = VectorsDB(client); + +DocumentList result = await vectorsDB.listDocuments( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + Query.limit(10) + ], +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.Query +import io.appwrite.services.VectorsDB + +val client = Client(context) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +val vectorsDB = VectorsDB(client) + +val response = vectorsDB.listDocuments( + databaseId = "<DATABASE_ID>", + collectionId = "<COLLECTION_ID>", + queries = listOf( + Query.limit(10) + ), +) +``` +```java +import io.appwrite.Client; +import io.appwrite.Query; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.VectorsDB; +import java.util.List; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +vectorsDB.listDocuments( + "<DATABASE_ID>", + "<COLLECTION_ID>", + List.of( + Query.limit(10) + ), + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +let vectorsDB = VectorsDB(client) + +let documentList = try await vectorsDB.listDocuments( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + queries: [ + Query.limit(10) + ] +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; +use appwrite::query::Query; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.list_documents( + "<DATABASE_ID>", + "<COLLECTION_ID>", + Some(vec![Query::limit(10).to_string()]), + None, // transactionId (optional) + None, // total (optional) + None, // ttl (optional) + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"limit","values":[10]}' +``` +{% /multicode %} + +# Update document {% #update-document %} +Use the `updateDocument` method to update a document. The update is a patch, so you only pass the fields you want to change. To change the vector, pass a new `embeddings` array of the same length as the collection's `dimension`. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.updateDocument({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + data: { + embeddings: [0.20, 0.10, 0.60, 0.10], + metadata: { title: 'Hamlet', year: 1602 } + } +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.updateDocument({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + data: { + embeddings: [0.20, 0.10, 0.60, 0.10], + metadata: { title: 'Hamlet', year: 1602 } + } +}); +``` +```php +<?php + +use Appwrite\Client; +use Appwrite\Services\VectorsDB; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('<YOUR_PROJECT_ID>') // Your project ID + ->setKey('<YOUR_API_KEY>'); // Your secret API key + +$vectorsDB = new VectorsDB($client); + +$result = $vectorsDB->updateDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + data: [ + 'embeddings' => [0.20, 0.10, 0.60, 0.10], + 'metadata' => ['title' => 'Hamlet', 'year' => 1602] + ] +); +``` +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('<YOUR_PROJECT_ID>') # Your project ID +client.set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB(client) + +result = vectors_db.update_document( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>', + document_id = '<DOCUMENT_ID>', + data = { + "embeddings": [0.20, 0.10, 0.60, 0.10], + "metadata": { "title": "Hamlet", "year": 1602 } + } +) +``` +```ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('<YOUR_PROJECT_ID>') # Your project ID + .set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB.new(client) + +result = vectors_db.update_document( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + document_id: '<DOCUMENT_ID>', + data: { + "embeddings" => [0.20, 0.10, 0.60, 0.10], + "metadata" => { "title" => "Hamlet", "year" => 1602 } + } +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("<YOUR_PROJECT_ID>") // Your project ID + .SetKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +Document result = await vectorsDB.UpdateDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: "<DOCUMENT_ID>", + data: new Dictionary<string, object> { + { "embeddings", new List<double> { 0.20, 0.10, 0.60, 0.10 } }, + { "metadata", new Dictionary<string, object> { { "title", "Hamlet" }, { "year", 1602 } } } + } +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +VectorsDB vectorsDB = VectorsDB(client); + +Document result = await vectorsDB.updateDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + data: { + "embeddings": [0.20, 0.10, 0.60, 0.10], + "metadata": { "title": "Hamlet", "year": 1602 } + }, +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.services.VectorsDB + +val client = Client(context) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +val vectorsDB = VectorsDB(client) + +val response = vectorsDB.updateDocument( + databaseId = "<DATABASE_ID>", + collectionId = "<COLLECTION_ID>", + documentId = "<DOCUMENT_ID>", + data = mapOf( + "embeddings" to listOf(0.20, 0.10, 0.60, 0.10), + "metadata" to mapOf("title" to "Hamlet", "year" to 1602) + ), +) +``` +```java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.VectorsDB; +import java.util.List; +import java.util.Map; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +vectorsDB.updateDocument( + "<DATABASE_ID>", + "<COLLECTION_ID>", + "<DOCUMENT_ID>", + Map.of( + "embeddings", List.of(0.20, 0.10, 0.60, 0.10), + "metadata", Map.of("title", "Hamlet", "year", 1602) + ), + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +let vectorsDB = VectorsDB(client) + +let document = try await vectorsDB.updateDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: "<DOCUMENT_ID>", + data: [ + "embeddings": [0.20, 0.10, 0.60, 0.10], + "metadata": ["title": "Hamlet", "year": 1602] + ] +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; +use serde_json::json; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.update_document( + "<DATABASE_ID>", + "<COLLECTION_ID>", + "<DOCUMENT_ID>", + Some(json!({ + "embeddings": [0.20, 0.10, 0.60, 0.10], + "metadata": { "title": "Hamlet", "year": 1602 } + })), + None, // permissions (optional) + None, // transactionId (optional) + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite vectors-db update-document \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --document-id <DOCUMENT_ID> \ + --data '{ "embeddings": [0.20, 0.10, 0.60, 0.10], "metadata": { "title": "Hamlet", "year": 1602 } }' +``` +{% /multicode %} + +# Upsert document {% #upsert-document %} +Use the `upsertDocument` method to create a document if it doesn't exist, or update it if it does. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.upsertDocument({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + data: { + embeddings: [0.50, 0.50, 0.50, 0.50], + metadata: { title: 'Hamlet', year: 1603 } + } +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.upsertDocument({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + data: { + embeddings: [0.50, 0.50, 0.50, 0.50], + metadata: { title: 'Hamlet', year: 1603 } + } +}); +``` +```php +<?php + +use Appwrite\Client; +use Appwrite\Services\VectorsDB; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('<YOUR_PROJECT_ID>') // Your project ID + ->setKey('<YOUR_API_KEY>'); // Your secret API key + +$vectorsDB = new VectorsDB($client); + +$result = $vectorsDB->upsertDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + data: [ + 'embeddings' => [0.50, 0.50, 0.50, 0.50], + 'metadata' => ['title' => 'Hamlet', 'year' => 1603] + ] +); +``` +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('<YOUR_PROJECT_ID>') # Your project ID +client.set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB(client) + +result = vectors_db.upsert_document( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>', + document_id = '<DOCUMENT_ID>', + data = { + "embeddings": [0.50, 0.50, 0.50, 0.50], + "metadata": { "title": "Hamlet", "year": 1603 } + } +) +``` +```ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('<YOUR_PROJECT_ID>') # Your project ID + .set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB.new(client) + +result = vectors_db.upsert_document( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + document_id: '<DOCUMENT_ID>', + data: { + "embeddings" => [0.50, 0.50, 0.50, 0.50], + "metadata" => { "title" => "Hamlet", "year" => 1603 } + } +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("<YOUR_PROJECT_ID>") // Your project ID + .SetKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +Document result = await vectorsDB.UpsertDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: "<DOCUMENT_ID>", + data: new Dictionary<string, object> { + { "embeddings", new List<double> { 0.50, 0.50, 0.50, 0.50 } }, + { "metadata", new Dictionary<string, object> { { "title", "Hamlet" }, { "year", 1603 } } } + } +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +VectorsDB vectorsDB = VectorsDB(client); + +Document result = await vectorsDB.upsertDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + data: { + "embeddings": [0.50, 0.50, 0.50, 0.50], + "metadata": { "title": "Hamlet", "year": 1603 } + }, +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.services.VectorsDB + +val client = Client(context) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +val vectorsDB = VectorsDB(client) + +val response = vectorsDB.upsertDocument( + databaseId = "<DATABASE_ID>", + collectionId = "<COLLECTION_ID>", + documentId = "<DOCUMENT_ID>", + data = mapOf( + "embeddings" to listOf(0.50, 0.50, 0.50, 0.50), + "metadata" to mapOf("title" to "Hamlet", "year" to 1603) + ), +) +``` +```java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.VectorsDB; +import java.util.List; +import java.util.Map; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +vectorsDB.upsertDocument( + "<DATABASE_ID>", + "<COLLECTION_ID>", + "<DOCUMENT_ID>", + Map.of( + "embeddings", List.of(0.50, 0.50, 0.50, 0.50), + "metadata", Map.of("title", "Hamlet", "year", 1603) + ), + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +let vectorsDB = VectorsDB(client) + +let document = try await vectorsDB.upsertDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: "<DOCUMENT_ID>", + data: [ + "embeddings": [0.50, 0.50, 0.50, 0.50], + "metadata": ["title": "Hamlet", "year": 1603] + ] +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; +use serde_json::json; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.upsert_document( + "<DATABASE_ID>", + "<COLLECTION_ID>", + "<DOCUMENT_ID>", + Some(json!({ + "embeddings": [0.50, 0.50, 0.50, 0.50], + "metadata": { "title": "Hamlet", "year": 1603 } + })), + None, // permissions (optional) + None, // transactionId (optional) + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite vectors-db upsert-document \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --document-id <DOCUMENT_ID> \ + --data '{ "embeddings": [0.50, 0.50, 0.50, 0.50], "metadata": { "title": "Hamlet", "year": 1603 } }' +``` +{% /multicode %} + +# Delete document {% #delete-document %} +Use the `deleteDocument` method to remove a document from a collection. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.deleteDocument({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>' +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.deleteDocument({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>' +}); +``` +```php +<?php + +use Appwrite\Client; +use Appwrite\Services\VectorsDB; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('<YOUR_PROJECT_ID>') // Your project ID + ->setKey('<YOUR_API_KEY>'); // Your secret API key + +$vectorsDB = new VectorsDB($client); + +$result = $vectorsDB->deleteDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>' +); +``` +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('<YOUR_PROJECT_ID>') # Your project ID +client.set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB(client) + +result = vectors_db.delete_document( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>', + document_id = '<DOCUMENT_ID>' +) +``` +```ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('<YOUR_PROJECT_ID>') # Your project ID + .set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB.new(client) + +result = vectors_db.delete_document( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + document_id: '<DOCUMENT_ID>' +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("<YOUR_PROJECT_ID>") // Your project ID + .SetKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +await vectorsDB.DeleteDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: "<DOCUMENT_ID>" +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +VectorsDB vectorsDB = VectorsDB(client); + +await vectorsDB.deleteDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.services.VectorsDB + +val client = Client(context) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +val vectorsDB = VectorsDB(client) + +vectorsDB.deleteDocument( + databaseId = "<DATABASE_ID>", + collectionId = "<COLLECTION_ID>", + documentId = "<DOCUMENT_ID>", +) +``` +```java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.VectorsDB; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +vectorsDB.deleteDocument( + "<DATABASE_ID>", + "<COLLECTION_ID>", + "<DOCUMENT_ID>", + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println("Deleted"); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +let vectorsDB = VectorsDB(client) + +try await vectorsDB.deleteDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: "<DOCUMENT_ID>" +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + vectors_db.delete_document( + "<DATABASE_ID>", + "<COLLECTION_ID>", + "<DOCUMENT_ID>", + None, // transactionId (optional) + ).await?; + + Ok(()) +} +``` +```bash +appwrite vectors-db delete-document \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --document-id <DOCUMENT_ID> +``` +{% /multicode %} + +# Permissions {% #permissions %} +To access documents through a [Client SDK](/docs/sdks#client), you must grant the relevant permissions. +By default, Appwrite doesn't grant any user permissions when a new collection is created. + +You can configure permissions at the collection level, or enable `documentSecurity` on the collection to also set permissions on individual documents. + +[Learn about configuring permissions](/docs/products/databases/vectorsdb/permissions). + +# Next steps {% #next-steps %} + +Continue learning with these related guides: + +{% cards %} +{% cards_item href="/docs/products/databases/vectorsdb/vector-search" title="Vector search" %} +Rank documents by similarity to a query vector using cosine, dot product, or Euclidean distance. +{% /cards_item %} + +{% cards_item href="/docs/products/databases/vectorsdb/bulk-operations" title="Bulk operations" %} +Create, update, upsert, and delete many documents in a single request. +{% /cards_item %} + +{% cards_item href="/docs/products/databases/vectorsdb/collections" title="Collections" %} +Configure the dimension and indexes that define how your vectors are stored and searched. +{% /cards_item %} +{% /cards %} diff --git a/src/routes/docs/products/databases/vectorsdb/embeddings/+page.markdoc b/src/routes/docs/products/databases/vectorsdb/embeddings/+page.markdoc new file mode 100644 index 00000000000..5730c4365fc --- /dev/null +++ b/src/routes/docs/products/databases/vectorsdb/embeddings/+page.markdoc @@ -0,0 +1,612 @@ +--- +layout: article +title: Embeddings +description: Generate text embeddings with Appwrite VectorsDB. Turn text into vector embeddings with built-in models and store them in your documents for vector search. +--- +An embedding is a list of numbers that represents the meaning of a piece of text. +VectorsDB can generate embeddings for you with built-in models, so you can turn text into vectors and store them in a collection without running a separate embedding service. + +The typical flow is two steps: generate an embedding from your text, then store that embedding in a document's `embeddings` field. Once stored, you can run [vector search](/docs/products/databases/vectorsdb/vector-search) over your documents. + +# Generate embeddings {% #generate-embeddings %} +Use the `createTextEmbeddings` method to turn one or more strings into vector embeddings. Pass an array of `texts` and, optionally, a `model`. When you omit `model`, VectorsDB uses the default `nomic-embed-text` model. Appwrite [Server SDKs](/docs/sdks#server) require an [API key](/docs/advanced/platform/api-keys). + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.createTextEmbeddings({ + texts: ['The quick brown fox jumps over the lazy dog'], + model: sdk.EmbeddingModel.Nomicembedtext // optional, defaults to nomic-embed-text +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.createTextEmbeddings({ + texts: ['The quick brown fox jumps over the lazy dog'], + model: sdk.EmbeddingModel.Nomicembedtext // optional, defaults to nomic-embed-text +}); +``` +```php +<?php + +use Appwrite\Client; +use Appwrite\Services\VectorsDB; +use Appwrite\Enums\EmbeddingModel; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('<YOUR_PROJECT_ID>') // Your project ID + ->setKey('<YOUR_API_KEY>'); // Your secret API key + +$vectorsDB = new VectorsDB($client); + +$result = $vectorsDB->createTextEmbeddings( + texts: ['The quick brown fox jumps over the lazy dog'], + model: EmbeddingModel::NOMICEMBEDTEXT() // optional, defaults to nomic-embed-text +); +``` +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB +from appwrite.enums import EmbeddingModel + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('<YOUR_PROJECT_ID>') # Your project ID +client.set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB(client) + +result = vectors_db.create_text_embeddings( + texts = ['The quick brown fox jumps over the lazy dog'], + model = EmbeddingModel.NOMIC_EMBED_TEXT # optional, defaults to nomic-embed-text +) +``` +```ruby +require 'appwrite' + +include Appwrite +include Appwrite::Enums + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('<YOUR_PROJECT_ID>') # Your project ID + .set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB.new(client) + +result = vectors_db.create_text_embeddings( + texts: ['The quick brown fox jumps over the lazy dog'], + model: EmbeddingModel::NOMIC_EMBED_TEXT # optional, defaults to nomic-embed-text +) +``` +```csharp +using Appwrite; +using Appwrite.Enums; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("<YOUR_PROJECT_ID>") // Your project ID + .SetKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +EmbeddingList result = await vectorsDB.CreateTextEmbeddings( + texts: new List<string> { "The quick brown fox jumps over the lazy dog" }, + model: EmbeddingModel.NomicEmbedText // optional, defaults to nomic-embed-text +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; +import 'package:dart_appwrite/enums.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +VectorsDB vectorsDB = VectorsDB(client); + +EmbeddingList result = await vectorsDB.createTextEmbeddings( + texts: ['The quick brown fox jumps over the lazy dog'], + model: EmbeddingModel.nomicEmbedText, // optional, defaults to nomic-embed-text +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.enums.EmbeddingModel +import io.appwrite.services.VectorsDB + +val client = Client(context) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +val vectorsDB = VectorsDB(client) + +val response = vectorsDB.createTextEmbeddings( + texts = listOf("The quick brown fox jumps over the lazy dog"), + model = EmbeddingModel.NOMIC_EMBED_TEXT, // optional, defaults to nomic-embed-text +) +``` +```java +import io.appwrite.Client; +import io.appwrite.enums.EmbeddingModel; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.VectorsDB; +import java.util.List; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +vectorsDB.createTextEmbeddings( + List.of("The quick brown fox jumps over the lazy dog"), + EmbeddingModel.NOMIC_EMBED_TEXT, // optional, defaults to nomic-embed-text + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite +import AppwriteEnums + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +let vectorsDB = VectorsDB(client) + +let embeddingList = try await vectorsDB.createTextEmbeddings( + texts: ["The quick brown fox jumps over the lazy dog"], + model: .nomicEmbedText // optional, defaults to nomic-embed-text +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; +use appwrite::enums::EmbeddingModel; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.create_text_embeddings( + vec!["The quick brown fox jumps over the lazy dog"], + Some(EmbeddingModel::NomicEmbedText), // optional, defaults to nomic-embed-text + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite vectors-db create-text-embeddings \ + --texts 'The quick brown fox jumps over the lazy dog' \ + --model 'nomic-embed-text' +``` +{% /multicode %} + +The response is an embedding list. The `embeddings` array holds one entry per input text, in the same order you passed them. + +```json +{ + "total": 1, + "embeddings": [ + { + "model": "nomic-embed-text", + "dimension": 768, + "embedding": [-0.012246467, 0.02621112, -0.15247375, ...], + "error": "" + } + ] +} +``` + +Each entry contains: + +| Field | Description | +| --- | --- | +| `model` | The model that generated this embedding. | +| `dimension` | The number of values in the embedding vector. | +| `embedding` | The embedding vector as an array of floats. If generation fails, this is an empty array. | +| `error` | An error message if this text could not be embedded. An empty string means there was no error. | + +# Available models {% #available-models %} +VectorsDB ships with the following text embedding models. The `dimension` of a model is the length of the vector it produces, and it must match the `dimension` you set on the [collection](/docs/products/databases/vectorsdb/collections) where you store the embeddings. + +| Model | Dimension | Notes | +| --- | --- | --- | +| `nomic-embed-text` | 768 | Default model, used when you omit `model`. | +| `embedding-gemma` | 768 | | +| `all-minilm` | 384 | | +| `bge-small` | 384 | | + +{% info title="Match the model to your collection dimension" %} +Pick a model before you create your collection, then set the collection's `dimension` to that model's dimension. All documents in a collection must use vectors of the same dimension, so a single collection works with models of one dimension only. +{% /info %} + +# Store embeddings {% #store-embeddings %} +Once you have an embedding, store it in a document's `embeddings` field. The collection's `dimension` must match the embedding's `dimension`. You can store any related data alongside the vector in the document's `metadata` field. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const text = 'The quick brown fox jumps over the lazy dog'; + +const embeddings = await vectorsDB.createTextEmbeddings({ + texts: [text] +}); + +const result = await vectorsDB.createDocument({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: sdk.ID.unique(), + data: { + embeddings: embeddings.embeddings[0].embedding, + metadata: { text } + } +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const text = 'The quick brown fox jumps over the lazy dog'; + +const embeddings = await vectorsDB.createTextEmbeddings({ + texts: [text] +}); + +const result = await vectorsDB.createDocument({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: sdk.ID.unique(), + data: { + embeddings: embeddings.embeddings[0].embedding, + metadata: { text } + } +}); +``` +```php +<?php + +use Appwrite\Client; +use Appwrite\Services\VectorsDB; +use Appwrite\ID; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('<YOUR_PROJECT_ID>') // Your project ID + ->setKey('<YOUR_API_KEY>'); // Your secret API key + +$vectorsDB = new VectorsDB($client); + +$text = 'The quick brown fox jumps over the lazy dog'; + +$embeddings = $vectorsDB->createTextEmbeddings( + texts: [$text] +); + +$result = $vectorsDB->createDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: ID::unique(), + data: [ + 'embeddings' => $embeddings['embeddings'][0]['embedding'], + 'metadata' => ['text' => $text] + ] +); +``` +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB +from appwrite.id import ID + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('<YOUR_PROJECT_ID>') # Your project ID +client.set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB(client) + +text = 'The quick brown fox jumps over the lazy dog' + +embeddings = vectors_db.create_text_embeddings( + texts = [text] +) + +result = vectors_db.create_document( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>', + document_id = ID.unique(), + data = { + "embeddings": embeddings["embeddings"][0]["embedding"], + "metadata": { "text": text } + } +) +``` +```ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('<YOUR_PROJECT_ID>') # Your project ID + .set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB.new(client) + +text = 'The quick brown fox jumps over the lazy dog' + +embeddings = vectors_db.create_text_embeddings( + texts: [text] +) + +result = vectors_db.create_document( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + document_id: ID.unique(), + data: { + "embeddings" => embeddings.embeddings[0].embedding, + "metadata" => { "text" => text } + } +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("<YOUR_PROJECT_ID>") // Your project ID + .SetKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +var text = "The quick brown fox jumps over the lazy dog"; + +EmbeddingList embeddings = await vectorsDB.CreateTextEmbeddings( + texts: new List<string> { text } +); + +Document result = await vectorsDB.CreateDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: ID.Unique(), + data: new { + embeddings = embeddings.Embeddings[0].Embedding, + metadata = new { text } + } +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +VectorsDB vectorsDB = VectorsDB(client); + +final text = 'The quick brown fox jumps over the lazy dog'; + +EmbeddingList embeddings = await vectorsDB.createTextEmbeddings( + texts: [text], +); + +Document result = await vectorsDB.createDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: ID.unique(), + data: { + "embeddings": embeddings.embeddings[0].embedding, + "metadata": { "text": text } + }, +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.ID +import io.appwrite.services.VectorsDB + +val client = Client(context) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +val vectorsDB = VectorsDB(client) + +val text = "The quick brown fox jumps over the lazy dog" + +val embeddings = vectorsDB.createTextEmbeddings( + texts = listOf(text), +) + +val response = vectorsDB.createDocument( + databaseId = "<DATABASE_ID>", + collectionId = "<COLLECTION_ID>", + documentId = ID.unique(), + data = mapOf( + "embeddings" to embeddings.embeddings[0].embedding, + "metadata" to mapOf("text" to text) + ), +) +``` +```java +import io.appwrite.Client; +import io.appwrite.ID; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.VectorsDB; +import java.util.List; +import java.util.Map; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +String text = "The quick brown fox jumps over the lazy dog"; + +vectorsDB.createTextEmbeddings( + List.of(text), + new CoroutineCallback<>((embeddings, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + vectorsDB.createDocument( + "<DATABASE_ID>", + "<COLLECTION_ID>", + ID.unique(), + Map.of( + "embeddings", embeddings.getEmbeddings().get(0).getEmbedding(), + "metadata", Map.of("text", text) + ), + new CoroutineCallback<>((result, err) -> { + if (err != null) { + err.printStackTrace(); + return; + } + + System.out.println(result); + }) + ); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +let vectorsDB = VectorsDB(client) + +let text = "The quick brown fox jumps over the lazy dog" + +let embeddings = try await vectorsDB.createTextEmbeddings( + texts: [text] +) + +let document = try await vectorsDB.createDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: ID.unique(), + data: [ + "embeddings": embeddings.embeddings[0].embedding, + "metadata": ["text": text] + ] +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; +use appwrite::id::ID; +use serde_json::json; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + let text = "The quick brown fox jumps over the lazy dog"; + + let embeddings = vectors_db.create_text_embeddings( + vec![text], + None, // model (optional) + ).await?; + + let result = vectors_db.create_document( + "<DATABASE_ID>", + "<COLLECTION_ID>", + ID::unique(), + json!({ + "embeddings": embeddings.embeddings[0].embedding, + "metadata": { "text": text } + }), + None, // permissions (optional) + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite vectors-db create-document \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --document-id 'unique()' \ + --data '{ "embeddings": [-0.012246467, 0.02621112, -0.15247375], "metadata": { "text": "The quick brown fox jumps over the lazy dog" } }' +``` +{% /multicode %} + +{% info title="Embed in batches" %} +You can pass several strings in one `createTextEmbeddings` call to embed them together. The response returns one entry per input text, in order, so you can map each embedding back to its source text before storing. +{% /info %} + +# Next steps {% #next-steps %} +With embeddings stored in your documents, you can find the most similar documents to a query vector with vector search. + +{% arrow_link href="/docs/products/databases/vectorsdb/vector-search" %} +Learn about vector search +{% /arrow_link %} diff --git a/src/routes/docs/products/databases/vectorsdb/order/+page.markdoc b/src/routes/docs/products/databases/vectorsdb/order/+page.markdoc new file mode 100644 index 00000000000..160513898fa --- /dev/null +++ b/src/routes/docs/products/databases/vectorsdb/order/+page.markdoc @@ -0,0 +1,1006 @@ +--- +layout: article +title: Order +description: Order documents returned by Appwrite VectorsDB. Learn how to sort by system fields like $createdAt and $sequence, and why metadata sub-fields can't be ordered. +--- +You can order the documents returned by [listDocuments](/docs/products/databases/vectorsdb/documents#list-documents) using the `Query.orderAsc()` and `Query.orderDesc()` query methods. + +VectorsDB orders on the system fields that Appwrite maintains on every document, such as `$createdAt`, `$updatedAt`, `$sequence`, and `$id`. + +{% info title="Metadata sub-fields can't be ordered" %} +A VectorsDB collection has a [fixed schema](/docs/products/databases/vectorsdb/collections#schema): an `embeddings` vector and a `metadata` object. Because `metadata` is stored as a single JSON object rather than typed columns, you can't order by a value inside it. Ordering by a nested path like `metadata.title` is rejected with `Invalid query: Cannot order by nested attribute: metadata`. Order by the system fields below instead, or keep an orderable value in a system field such as `$createdAt`. +{% /info %} + +# Order by a system field {% #one-field %} +Pass `Query.orderAsc()` or `Query.orderDesc()` with a system field to sort the documents returned. The example below orders documents from newest to oldest by `$createdAt`. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.listDocuments({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + sdk.Query.orderDesc('$createdAt') + ] +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.listDocuments({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + sdk.Query.orderDesc('$createdAt') + ] +}); +``` +```php +<?php + +use Appwrite\Client; +use Appwrite\Services\VectorsDB; +use Appwrite\Query; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('<YOUR_PROJECT_ID>') // Your project ID + ->setKey('<YOUR_API_KEY>'); // Your secret API key + +$vectorsDB = new VectorsDB($client); + +$result = $vectorsDB->listDocuments( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + Query::orderDesc('$createdAt') + ] +); +``` +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB +from appwrite.query import Query + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('<YOUR_PROJECT_ID>') # Your project ID +client.set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB(client) + +result = vectors_db.list_documents( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>', + queries = [ + Query.order_desc('$createdAt') + ] +) +``` +```ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('<YOUR_PROJECT_ID>') # Your project ID + .set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB.new(client) + +result = vectors_db.list_documents( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + queries: [ + Query.order_desc('$createdAt') + ] +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("<YOUR_PROJECT_ID>") // Your project ID + .SetKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +DocumentList result = await vectorsDB.ListDocuments( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + queries: new List<string> { + Query.OrderDesc("$createdAt") + } +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +VectorsDB vectorsDB = VectorsDB(client); + +DocumentList result = await vectorsDB.listDocuments( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + Query.orderDesc('\$createdAt') + ], +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.Query +import io.appwrite.services.VectorsDB + +val client = Client(context) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +val vectorsDB = VectorsDB(client) + +val response = vectorsDB.listDocuments( + databaseId = "<DATABASE_ID>", + collectionId = "<COLLECTION_ID>", + queries = listOf( + Query.orderDesc("\$createdAt") + ), +) +``` +```java +import io.appwrite.Client; +import io.appwrite.Query; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.VectorsDB; +import java.util.List; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +vectorsDB.listDocuments( + "<DATABASE_ID>", + "<COLLECTION_ID>", + List.of( + Query.orderDesc("$createdAt") + ), + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +let vectorsDB = VectorsDB(client) + +let documentList = try await vectorsDB.listDocuments( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + queries: [ + Query.orderDesc("$createdAt") + ] +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; +use appwrite::query::Query; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.list_documents( + "<DATABASE_ID>", + "<COLLECTION_ID>", + Some(vec![Query::order_desc("$createdAt").to_string()]), + None, // transactionId (optional) + None, // total (optional) + None, // ttl (optional) + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"orderDesc","values":["$createdAt"]}' +``` +{% /multicode %} + +# Order by multiple fields {% #multiple-fields %} +To sort by more than one field, pass multiple order queries. They are applied in order, so the first query is the primary sort and each later query breaks ties. + +In the example below, documents are sorted first by `$createdAt` in descending order, then by `$id` in ascending order to break ties. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.listDocuments({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + sdk.Query.orderDesc('$createdAt'), // Order first by creation time, newest first + sdk.Query.orderAsc('$id') // Then break ties by document ID + ] +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.listDocuments({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + sdk.Query.orderDesc('$createdAt'), // Order first by creation time, newest first + sdk.Query.orderAsc('$id') // Then break ties by document ID + ] +}); +``` +```php +<?php + +use Appwrite\Client; +use Appwrite\Services\VectorsDB; +use Appwrite\Query; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('<YOUR_PROJECT_ID>') // Your project ID + ->setKey('<YOUR_API_KEY>'); // Your secret API key + +$vectorsDB = new VectorsDB($client); + +$result = $vectorsDB->listDocuments( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + Query::orderDesc('$createdAt'), + Query::orderAsc('$id') + ] +); +``` +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB +from appwrite.query import Query + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('<YOUR_PROJECT_ID>') # Your project ID +client.set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB(client) + +result = vectors_db.list_documents( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>', + queries = [ + Query.order_desc('$createdAt'), + Query.order_asc('$id') + ] +) +``` +```ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('<YOUR_PROJECT_ID>') # Your project ID + .set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB.new(client) + +result = vectors_db.list_documents( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + queries: [ + Query.order_desc('$createdAt'), + Query.order_asc('$id') + ] +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("<YOUR_PROJECT_ID>") // Your project ID + .SetKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +DocumentList result = await vectorsDB.ListDocuments( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + queries: new List<string> { + Query.OrderDesc("$createdAt"), + Query.OrderAsc("$id") + } +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +VectorsDB vectorsDB = VectorsDB(client); + +DocumentList result = await vectorsDB.listDocuments( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + Query.orderDesc('\$createdAt'), + Query.orderAsc('\$id') + ], +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.Query +import io.appwrite.services.VectorsDB + +val client = Client(context) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +val vectorsDB = VectorsDB(client) + +val response = vectorsDB.listDocuments( + databaseId = "<DATABASE_ID>", + collectionId = "<COLLECTION_ID>", + queries = listOf( + Query.orderDesc("\$createdAt"), + Query.orderAsc("\$id") + ), +) +``` +```java +import io.appwrite.Client; +import io.appwrite.Query; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.VectorsDB; +import java.util.List; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +vectorsDB.listDocuments( + "<DATABASE_ID>", + "<COLLECTION_ID>", + List.of( + Query.orderDesc("$createdAt"), + Query.orderAsc("$id") + ), + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +let vectorsDB = VectorsDB(client) + +let documentList = try await vectorsDB.listDocuments( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + queries: [ + Query.orderDesc("$createdAt"), + Query.orderAsc("$id") + ] +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; +use appwrite::query::Query; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.list_documents( + "<DATABASE_ID>", + "<COLLECTION_ID>", + Some(vec![ + Query::order_desc("$createdAt").to_string(), + Query::order_asc("$id").to_string(), + ]), + None, // transactionId (optional) + None, // total (optional) + None, // ttl (optional) + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"orderDesc","values":["$createdAt"]}' '{"method":"orderAsc","values":["$id"]}' +``` +{% /multicode %} + +# Order by sequence {% #sequence-ordering %} +For ordering based on insertion order, use the `$sequence` field, which Appwrite adds to every document. Sorting by `$sequence` returns documents in the order they were created. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.listDocuments({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + sdk.Query.orderAsc('$sequence') + ] +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.listDocuments({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + sdk.Query.orderAsc('$sequence') + ] +}); +``` +```php +<?php + +use Appwrite\Client; +use Appwrite\Services\VectorsDB; +use Appwrite\Query; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('<YOUR_PROJECT_ID>') // Your project ID + ->setKey('<YOUR_API_KEY>'); // Your secret API key + +$vectorsDB = new VectorsDB($client); + +$result = $vectorsDB->listDocuments( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + Query::orderAsc('$sequence') + ] +); +``` +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB +from appwrite.query import Query + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('<YOUR_PROJECT_ID>') # Your project ID +client.set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB(client) + +result = vectors_db.list_documents( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>', + queries = [ + Query.order_asc('$sequence') + ] +) +``` +```ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('<YOUR_PROJECT_ID>') # Your project ID + .set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB.new(client) + +result = vectors_db.list_documents( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + queries: [ + Query.order_asc('$sequence') + ] +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("<YOUR_PROJECT_ID>") // Your project ID + .SetKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +DocumentList result = await vectorsDB.ListDocuments( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + queries: new List<string> { + Query.OrderAsc("$sequence") + } +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +VectorsDB vectorsDB = VectorsDB(client); + +DocumentList result = await vectorsDB.listDocuments( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + Query.orderAsc('\$sequence') + ], +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.Query +import io.appwrite.services.VectorsDB + +val client = Client(context) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +val vectorsDB = VectorsDB(client) + +val response = vectorsDB.listDocuments( + databaseId = "<DATABASE_ID>", + collectionId = "<COLLECTION_ID>", + queries = listOf( + Query.orderAsc("\$sequence") + ), +) +``` +```java +import io.appwrite.Client; +import io.appwrite.Query; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.VectorsDB; +import java.util.List; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +vectorsDB.listDocuments( + "<DATABASE_ID>", + "<COLLECTION_ID>", + List.of( + Query.orderAsc("$sequence") + ), + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +let vectorsDB = VectorsDB(client) + +let documentList = try await vectorsDB.listDocuments( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + queries: [ + Query.orderAsc("$sequence") + ] +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; +use appwrite::query::Query; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.list_documents( + "<DATABASE_ID>", + "<COLLECTION_ID>", + Some(vec![Query::order_asc("$sequence").to_string()]), + None, // transactionId (optional) + None, // total (optional) + None, // ttl (optional) + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"orderAsc","values":["$sequence"]}' +``` +{% /multicode %} + +The `$sequence` field is useful when you need: +- Consistent ordering for pagination, especially with high-frequency inserts +- Reliable insertion order tracking when timestamps might not be precise enough +- Simple insertion-order sorting without managing custom counter fields + +# Order randomly {% #random-ordering %} +Use `Query.orderRandom()` to return documents in a random order. This is useful for sampling documents or surfacing varied results on each request. It takes no field. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.listDocuments({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + sdk.Query.orderRandom() + ] +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.listDocuments({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + sdk.Query.orderRandom() + ] +}); +``` +```php +<?php + +use Appwrite\Client; +use Appwrite\Services\VectorsDB; +use Appwrite\Query; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('<YOUR_PROJECT_ID>') // Your project ID + ->setKey('<YOUR_API_KEY>'); // Your secret API key + +$vectorsDB = new VectorsDB($client); + +$result = $vectorsDB->listDocuments( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + Query::orderRandom() + ] +); +``` +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB +from appwrite.query import Query + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('<YOUR_PROJECT_ID>') # Your project ID +client.set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB(client) + +result = vectors_db.list_documents( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>', + queries = [ + Query.order_random() + ] +) +``` +```ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('<YOUR_PROJECT_ID>') # Your project ID + .set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB.new(client) + +result = vectors_db.list_documents( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + queries: [ + Query.order_random() + ] +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("<YOUR_PROJECT_ID>") // Your project ID + .SetKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +DocumentList result = await vectorsDB.ListDocuments( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + queries: new List<string> { + Query.OrderRandom() + } +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +VectorsDB vectorsDB = VectorsDB(client); + +DocumentList result = await vectorsDB.listDocuments( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + Query.orderRandom() + ], +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.Query +import io.appwrite.services.VectorsDB + +val client = Client(context) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +val vectorsDB = VectorsDB(client) + +val response = vectorsDB.listDocuments( + databaseId = "<DATABASE_ID>", + collectionId = "<COLLECTION_ID>", + queries = listOf( + Query.orderRandom() + ), +) +``` +```java +import io.appwrite.Client; +import io.appwrite.Query; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.VectorsDB; +import java.util.List; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +vectorsDB.listDocuments( + "<DATABASE_ID>", + "<COLLECTION_ID>", + List.of( + Query.orderRandom() + ), + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +let vectorsDB = VectorsDB(client) + +let documentList = try await vectorsDB.listDocuments( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + queries: [ + Query.orderRandom() + ] +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; +use appwrite::query::Query; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.list_documents( + "<DATABASE_ID>", + "<COLLECTION_ID>", + Some(vec![Query::order_random().to_string()]), + None, // transactionId (optional) + None, // total (optional) + None, // ttl (optional) + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"orderRandom","values":[]}' +``` +{% /multicode %} + +To rank documents by similarity to a query vector instead of ordering by a field, use a vector search query. See [Vector search](/docs/products/databases/vectorsdb/vector-search). diff --git a/src/routes/docs/products/databases/vectorsdb/pagination/+page.markdoc b/src/routes/docs/products/databases/vectorsdb/pagination/+page.markdoc new file mode 100644 index 00000000000..c12e0d4cddc --- /dev/null +++ b/src/routes/docs/products/databases/vectorsdb/pagination/+page.markdoc @@ -0,0 +1,1041 @@ +--- +layout: article +title: Pagination +description: Implement pagination for large data sets in Appwrite VectorsDB. Explore techniques for splitting and displaying documents across multiple pages. +--- + +As your collection grows in size, you'll need to paginate the documents returned. +Pagination improves performance by returning a subset of documents that match a query at a time, called a page. + +By default, list operations return 25 documents per page, which can be changed using the `Query.limit()` query method. +There is no hard limit on the number of documents you can request. However, beware that **large pages can degrade performance**. + +# Offset pagination {% #offset-pagination %} + +Offset pagination divides documents into pages of `N` documents each. +To read page number `P`, skip `offset = N * (P - 1)` documents, then read the next `N`. + +Using `Query.limit()` and `Query.offset()` you can achieve offset pagination. +With `Query.limit()` you define how many documents can be returned from one request. +The `Query.offset()` is the number of documents you wish to skip before selecting documents. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +// Page 1 +const page1 = await vectorsDB.listDocuments({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + sdk.Query.limit(25), + sdk.Query.offset(0) + ] +}); + +// Page 2 +const page2 = await vectorsDB.listDocuments({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + sdk.Query.limit(25), + sdk.Query.offset(25) + ] +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +// Page 1 +const page1 = await vectorsDB.listDocuments({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + sdk.Query.limit(25), + sdk.Query.offset(0) + ] +}); + +// Page 2 +const page2 = await vectorsDB.listDocuments({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + sdk.Query.limit(25), + sdk.Query.offset(25) + ] +}); +``` +```php +<?php + +use Appwrite\Client; +use Appwrite\Services\VectorsDB; +use Appwrite\Query; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('<YOUR_PROJECT_ID>') // Your project ID + ->setKey('<YOUR_API_KEY>'); // Your secret API key + +$vectorsDB = new VectorsDB($client); + +// Page 1 +$page1 = $vectorsDB->listDocuments( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + Query::limit(25), + Query::offset(0) + ] +); + +// Page 2 +$page2 = $vectorsDB->listDocuments( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + Query::limit(25), + Query::offset(25) + ] +); +``` +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB +from appwrite.query import Query + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('<YOUR_PROJECT_ID>') # Your project ID +client.set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB(client) + +# Page 1 +page1 = vectors_db.list_documents( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>', + queries = [ + Query.limit(25), + Query.offset(0) + ] +) + +# Page 2 +page2 = vectors_db.list_documents( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>', + queries = [ + Query.limit(25), + Query.offset(25) + ] +) +``` +```ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('<YOUR_PROJECT_ID>') # Your project ID + .set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB.new(client) + +# Page 1 +page1 = vectors_db.list_documents( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + queries: [ + Query.limit(25), + Query.offset(0) + ] +) + +# Page 2 +page2 = vectors_db.list_documents( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + queries: [ + Query.limit(25), + Query.offset(25) + ] +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("<YOUR_PROJECT_ID>") // Your project ID + .SetKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +// Page 1 +DocumentList page1 = await vectorsDB.ListDocuments( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + queries: new List<string> { + Query.Limit(25), + Query.Offset(0) + } +); + +// Page 2 +DocumentList page2 = await vectorsDB.ListDocuments( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + queries: new List<string> { + Query.Limit(25), + Query.Offset(25) + } +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +VectorsDB vectorsDB = VectorsDB(client); + +// Page 1 +DocumentList page1 = await vectorsDB.listDocuments( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + Query.limit(25), + Query.offset(0) + ], +); + +// Page 2 +DocumentList page2 = await vectorsDB.listDocuments( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + Query.limit(25), + Query.offset(25) + ], +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.Query +import io.appwrite.services.VectorsDB + +val client = Client(context) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +val vectorsDB = VectorsDB(client) + +// Page 1 +val page1 = vectorsDB.listDocuments( + databaseId = "<DATABASE_ID>", + collectionId = "<COLLECTION_ID>", + queries = listOf( + Query.limit(25), + Query.offset(0) + ), +) + +// Page 2 +val page2 = vectorsDB.listDocuments( + databaseId = "<DATABASE_ID>", + collectionId = "<COLLECTION_ID>", + queries = listOf( + Query.limit(25), + Query.offset(25) + ), +) +``` +```java +import io.appwrite.Client; +import io.appwrite.Query; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.VectorsDB; +import java.util.List; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +vectorsDB.listDocuments( + "<DATABASE_ID>", + "<COLLECTION_ID>", + List.of( + Query.limit(25), + Query.offset(0) + ), + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +let vectorsDB = VectorsDB(client) + +// Page 1 +let page1 = try await vectorsDB.listDocuments( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + queries: [ + Query.limit(25), + Query.offset(0) + ] +) + +// Page 2 +let page2 = try await vectorsDB.listDocuments( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + queries: [ + Query.limit(25), + Query.offset(25) + ] +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; +use appwrite::query::Query; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + // Page 1 + let page1 = vectors_db.list_documents( + "<DATABASE_ID>", + "<COLLECTION_ID>", + Some(vec![ + Query::limit(25).to_string(), + Query::offset(0).to_string(), + ]), + None, // transactionId (optional) + None, // total (optional) + None, // ttl (optional) + ).await?; + + // Page 2 + let page2 = vectors_db.list_documents( + "<DATABASE_ID>", + "<COLLECTION_ID>", + Some(vec![ + Query::limit(25).to_string(), + Query::offset(25).to_string(), + ]), + None, // transactionId (optional) + None, // total (optional) + None, // ttl (optional) + ).await?; + + Ok(()) +} +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"limit","values":[25]}' '{"method":"offset","values":[25]}' +``` +{% /multicode %} + +{% info title="Drawbacks" %} +While traditional offset pagination is familiar, it comes with some drawbacks. +The request gets slower as the offset increases because the database has to skip over all the preceding documents before it can start selecting data. +If the data changes frequently, offset pagination will also produce **missing and duplicate** results. +{% /info %} + +# Cursor pagination {% #cursor-pagination %} + +The cursor is a unique identifier for a document that points to where the next page should start. +After reading a page of documents, pass the last document's ID into the `Query.cursorAfter(lastId)` query method to get the next page of documents. +Pass the first document's ID into the `Query.cursorBefore(firstId)` query method to retrieve the previous page. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +// Page 1 +const page1 = await vectorsDB.listDocuments({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + sdk.Query.limit(25) + ] +}); + +const lastId = page1.documents[page1.documents.length - 1].$id; + +// Page 2 +const page2 = await vectorsDB.listDocuments({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + sdk.Query.limit(25), + sdk.Query.cursorAfter(lastId) + ] +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +// Page 1 +const page1 = await vectorsDB.listDocuments({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + sdk.Query.limit(25) + ] +}); + +const lastId = page1.documents[page1.documents.length - 1].$id; + +// Page 2 +const page2 = await vectorsDB.listDocuments({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + sdk.Query.limit(25), + sdk.Query.cursorAfter(lastId) + ] +}); +``` +```php +<?php + +use Appwrite\Client; +use Appwrite\Services\VectorsDB; +use Appwrite\Query; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('<YOUR_PROJECT_ID>') // Your project ID + ->setKey('<YOUR_API_KEY>'); // Your secret API key + +$vectorsDB = new VectorsDB($client); + +// Page 1 +$page1 = $vectorsDB->listDocuments( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + Query::limit(25) + ] +); + +$lastId = $page1['documents'][count($page1['documents']) - 1]['$id']; + +// Page 2 +$page2 = $vectorsDB->listDocuments( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + Query::limit(25), + Query::cursorAfter($lastId) + ] +); +``` +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB +from appwrite.query import Query + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('<YOUR_PROJECT_ID>') # Your project ID +client.set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB(client) + +# Page 1 +page1 = vectors_db.list_documents( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>', + queries = [ + Query.limit(25) + ] +) + +last_id = page1['documents'][-1]['$id'] + +# Page 2 +page2 = vectors_db.list_documents( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>', + queries = [ + Query.limit(25), + Query.cursor_after(last_id) + ] +) +``` +```ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('<YOUR_PROJECT_ID>') # Your project ID + .set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB.new(client) + +# Page 1 +page1 = vectors_db.list_documents( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + queries: [ + Query.limit(25) + ] +) + +last_id = page1.documents.last.id + +# Page 2 +page2 = vectors_db.list_documents( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + queries: [ + Query.limit(25), + Query.cursor_after(last_id) + ] +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("<YOUR_PROJECT_ID>") // Your project ID + .SetKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +// Page 1 +DocumentList page1 = await vectorsDB.ListDocuments( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + queries: new List<string> { + Query.Limit(25) + } +); + +string lastId = page1.Documents.Last().Id; + +// Page 2 +DocumentList page2 = await vectorsDB.ListDocuments( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + queries: new List<string> { + Query.Limit(25), + Query.CursorAfter(lastId) + } +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +VectorsDB vectorsDB = VectorsDB(client); + +// Page 1 +DocumentList page1 = await vectorsDB.listDocuments( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + Query.limit(25) + ], +); + +final lastId = page1.documents.last.$id; + +// Page 2 +DocumentList page2 = await vectorsDB.listDocuments( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + Query.limit(25), + Query.cursorAfter(lastId) + ], +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.Query +import io.appwrite.services.VectorsDB + +val client = Client(context) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +val vectorsDB = VectorsDB(client) + +// Page 1 +val page1 = vectorsDB.listDocuments( + databaseId = "<DATABASE_ID>", + collectionId = "<COLLECTION_ID>", + queries = listOf( + Query.limit(25) + ), +) + +val lastId = page1.documents.last().id + +// Page 2 +val page2 = vectorsDB.listDocuments( + databaseId = "<DATABASE_ID>", + collectionId = "<COLLECTION_ID>", + queries = listOf( + Query.limit(25), + Query.cursorAfter(lastId) + ), +) +``` +```java +import io.appwrite.Client; +import io.appwrite.Query; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.VectorsDB; +import java.util.List; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +vectorsDB.listDocuments( + "<DATABASE_ID>", + "<COLLECTION_ID>", + List.of( + Query.limit(25), + Query.cursorAfter("<LAST_DOCUMENT_ID>") + ), + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +let vectorsDB = VectorsDB(client) + +// Page 1 +let page1 = try await vectorsDB.listDocuments( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + queries: [ + Query.limit(25) + ] +) + +let lastId = page1.documents.last!.id + +// Page 2 +let page2 = try await vectorsDB.listDocuments( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + queries: [ + Query.limit(25), + Query.cursorAfter(lastId) + ] +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; +use appwrite::query::Query; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + // Page 1 + let page1 = vectors_db.list_documents( + "<DATABASE_ID>", + "<COLLECTION_ID>", + Some(vec![Query::limit(25).to_string()]), + None, // transactionId (optional) + None, // total (optional) + None, // ttl (optional) + ).await?; + + let last_id = page1.documents.last().unwrap().id.clone(); + + // Page 2 + let page2 = vectors_db.list_documents( + "<DATABASE_ID>", + "<COLLECTION_ID>", + Some(vec![ + Query::limit(25).to_string(), + Query::cursor_after(last_id).to_string(), + ]), + None, // transactionId (optional) + None, // total (optional) + None, // ttl (optional) + ).await?; + + Ok(()) +} +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"limit","values":[25]}' '{"method":"cursorAfter","values":["<LAST_DOCUMENT_ID>"]}' +``` +{% /multicode %} + +# When to use what? {% #when-to-use %} +Offset pagination should be used for collections that rarely change. +Offset pagination lets you build an indicator of the current page number and the total page count. +For example, a list with up to 20 pages or static data like a list of countries or currencies. +Using offset pagination on large and frequently updated collections may result in slow performance and **missing and duplicate** results. + +Cursor pagination should be used for frequently updated collections. +It is best suited for lazy-loaded pages with infinite scrolling. +For example, a feed, comment section, chat history, or high volume datasets. + +# Cache list responses {% #cache-list-responses %} + +You can cache list responses by passing a `ttl` (time-to-live) value in seconds. Subsequent identical requests return the cached result until the TTL expires. The cache is permission-aware, so users with different roles never see each other's cached data. + +Set `ttl` between `1` and `86400` (24 hours). The default is `0` (caching disabled). The response includes an `X-Appwrite-Cache` header with value `hit` or `miss`. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const page = await vectorsDB.listDocuments({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + sdk.Query.limit(25) + ], + ttl: 60 // Cache for 60 seconds +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const page = await vectorsDB.listDocuments({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + sdk.Query.limit(25) + ], + ttl: 60 // Cache for 60 seconds +}); +``` +```php +<?php + +use Appwrite\Client; +use Appwrite\Services\VectorsDB; +use Appwrite\Query; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('<YOUR_PROJECT_ID>') // Your project ID + ->setKey('<YOUR_API_KEY>'); // Your secret API key + +$vectorsDB = new VectorsDB($client); + +$page = $vectorsDB->listDocuments( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + Query::limit(25) + ], + ttl: 60 // Cache for 60 seconds +); +``` +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB +from appwrite.query import Query + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('<YOUR_PROJECT_ID>') # Your project ID +client.set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB(client) + +page = vectors_db.list_documents( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>', + queries = [ + Query.limit(25) + ], + ttl = 60 # Cache for 60 seconds +) +``` +```ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('<YOUR_PROJECT_ID>') # Your project ID + .set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB.new(client) + +page = vectors_db.list_documents( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + queries: [ + Query.limit(25) + ], + ttl: 60 # Cache for 60 seconds +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("<YOUR_PROJECT_ID>") // Your project ID + .SetKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +DocumentList page = await vectorsDB.ListDocuments( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + queries: new List<string> { + Query.Limit(25) + }, + ttl: 60 // Cache for 60 seconds +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +VectorsDB vectorsDB = VectorsDB(client); + +DocumentList page = await vectorsDB.listDocuments( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + Query.limit(25) + ], + ttl: 60, // Cache for 60 seconds +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.Query +import io.appwrite.services.VectorsDB + +val client = Client(context) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +val vectorsDB = VectorsDB(client) + +val page = vectorsDB.listDocuments( + databaseId = "<DATABASE_ID>", + collectionId = "<COLLECTION_ID>", + queries = listOf( + Query.limit(25) + ), + ttl = 60 // Cache for 60 seconds +) +``` +```java +import io.appwrite.Client; +import io.appwrite.Query; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.VectorsDB; +import java.util.List; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +vectorsDB.listDocuments( + "<DATABASE_ID>", + "<COLLECTION_ID>", + List.of( + Query.limit(25) + ), + null, // transactionId + null, // total + 60, // ttl - Cache for 60 seconds + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +let vectorsDB = VectorsDB(client) + +let page = try await vectorsDB.listDocuments( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + queries: [ + Query.limit(25) + ], + ttl: 60 // Cache for 60 seconds +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; +use appwrite::query::Query; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + let page = vectors_db.list_documents( + "<DATABASE_ID>", + "<COLLECTION_ID>", + Some(vec![Query::limit(25).to_string()]), + None, // transactionId (optional) + None, // total (optional) + Some(60), // ttl - Cache for 60 seconds + ).await?; + + println!("{:?}", page); + Ok(()) +} +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"limit","values":[25]}' \ + --ttl 60 +``` +{% /multicode %} + +Document writes do **not** invalidate the cache, so cached responses may contain stale data until the TTL expires. Use a short TTL for collections that change often, or skip caching entirely when you always need the latest documents. diff --git a/src/routes/docs/products/databases/vectorsdb/permissions/+page.markdoc b/src/routes/docs/products/databases/vectorsdb/permissions/+page.markdoc new file mode 100644 index 00000000000..2b3adc1c581 --- /dev/null +++ b/src/routes/docs/products/databases/vectorsdb/permissions/+page.markdoc @@ -0,0 +1,1241 @@ +--- +layout: article +title: Database permissions +description: Control access to your VectorsDB data with permissions. Learn how to set collection level and document level access rules. +--- + +Permissions define who can access documents in a collection. By default **no permissions** are granted to any users, so no user can access any documents. +Permissions exist at two levels, collection level and document level permissions. + +In Appwrite, permissions are **granted**, meaning a user has no access by default and receives access when granted. +A user with access granted at either collection level or document level will be able to access a document. +Users **don't need access at both levels** to access documents. + +Permissions are evaluated when documents are accessed through a [Client SDK](/docs/sdks#client). [Server SDKs](/docs/sdks#server) authenticated with an [API key](/docs/advanced/platform/api-keys) bypass permissions, so the examples below use a Server SDK to set and read back the permissions that a client would then be evaluated against. + +# Collection level {% #collection-level %} +Collection level permissions apply to every document in the collection. +If a user has read, create, update, or delete permissions at the collection level, the user can access **all documents** inside the collection. + +Configure collection level permissions by navigating to **Your collection** > **Security** > **Permissions**, or pass a `permissions` array when you create or update the collection. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.createCollection({ + databaseId: '<DATABASE_ID>', + collectionId: sdk.ID.unique(), + name: 'documents', + dimension: 4, + permissions: [ + sdk.Permission.read(sdk.Role.any()), + sdk.Permission.create(sdk.Role.users()), + sdk.Permission.update(sdk.Role.users()), + sdk.Permission.delete(sdk.Role.users()) + ], + documentSecurity: true // optional +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.createCollection({ + databaseId: '<DATABASE_ID>', + collectionId: sdk.ID.unique(), + name: 'documents', + dimension: 4, + permissions: [ + sdk.Permission.read(sdk.Role.any()), + sdk.Permission.create(sdk.Role.users()), + sdk.Permission.update(sdk.Role.users()), + sdk.Permission.delete(sdk.Role.users()) + ], + documentSecurity: true // optional +}); +``` +```php +<?php + +use Appwrite\Client; +use Appwrite\Services\VectorsDB; +use Appwrite\ID; +use Appwrite\Permission; +use Appwrite\Role; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('<YOUR_PROJECT_ID>') // Your project ID + ->setKey('<YOUR_API_KEY>'); // Your secret API key + +$vectorsDB = new VectorsDB($client); + +$result = $vectorsDB->createCollection( + databaseId: '<DATABASE_ID>', + collectionId: ID::unique(), + name: 'documents', + dimension: 4, + permissions: [ + Permission::read(Role::any()), + Permission::create(Role::users()), + Permission::update(Role::users()), + Permission::delete(Role::users()) + ], + documentSecurity: true // optional +); +``` +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB +from appwrite.id import ID +from appwrite.permission import Permission +from appwrite.role import Role + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('<YOUR_PROJECT_ID>') # Your project ID +client.set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB(client) + +result = vectors_db.create_collection( + database_id = '<DATABASE_ID>', + collection_id = ID.unique(), + name = 'documents', + dimension = 4, + permissions = [ + Permission.read(Role.any()), + Permission.create(Role.users()), + Permission.update(Role.users()), + Permission.delete(Role.users()) + ], + document_security = True # optional +) +``` +```ruby +require 'appwrite' + +include Appwrite +include Appwrite::Permission +include Appwrite::Role + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('<YOUR_PROJECT_ID>') # Your project ID + .set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB.new(client) + +result = vectors_db.create_collection( + database_id: '<DATABASE_ID>', + collection_id: ID.unique(), + name: 'documents', + dimension: 4, + permissions: [ + Permission.read(Role.any()), + Permission.create(Role.users()), + Permission.update(Role.users()), + Permission.delete(Role.users()) + ], + document_security: true # optional +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("<YOUR_PROJECT_ID>") // Your project ID + .SetKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +Collection result = await vectorsDB.CreateCollection( + databaseId: "<DATABASE_ID>", + collectionId: ID.Unique(), + name: "documents", + dimension: 4, + permissions: new List<string> { + Permission.Read(Role.Any()), + Permission.Create(Role.Users()), + Permission.Update(Role.Users()), + Permission.Delete(Role.Users()) + }, + documentSecurity: true // optional +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; +import 'package:dart_appwrite/permission.dart'; +import 'package:dart_appwrite/role.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +VectorsDB vectorsDB = VectorsDB(client); + +Collection result = await vectorsDB.createCollection( + databaseId: '<DATABASE_ID>', + collectionId: ID.unique(), + name: 'documents', + dimension: 4, + permissions: [ + Permission.read(Role.any()), + Permission.create(Role.users()), + Permission.update(Role.users()), + Permission.delete(Role.users()) + ], // (optional) + documentSecurity: true, // (optional) +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.ID +import io.appwrite.Permission +import io.appwrite.Role +import io.appwrite.services.VectorsDB + +val client = Client(context) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +val vectorsDB = VectorsDB(client) + +val response = vectorsDB.createCollection( + databaseId = "<DATABASE_ID>", + collectionId = ID.unique(), + name = "documents", + dimension = 4, + permissions = listOf( + Permission.read(Role.any()), + Permission.create(Role.users()), + Permission.update(Role.users()), + Permission.delete(Role.users()) + ), // optional + documentSecurity = true, // optional +) +``` +```java +import io.appwrite.Client; +import io.appwrite.ID; +import io.appwrite.Permission; +import io.appwrite.Role; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.VectorsDB; +import java.util.List; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +vectorsDB.createCollection( + "<DATABASE_ID>", + ID.unique(), + "documents", + 4, + List.of( + Permission.read(Role.any()), + Permission.create(Role.users()), + Permission.update(Role.users()), + Permission.delete(Role.users()) + ), + true, + true, + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +let vectorsDB = VectorsDB(client) + +let collection = try await vectorsDB.createCollection( + databaseId: "<DATABASE_ID>", + collectionId: ID.unique(), + name: "documents", + dimension: 4, + permissions: [ + Permission.read(Role.any()), + Permission.create(Role.users()), + Permission.update(Role.users()), + Permission.delete(Role.users()) + ], + documentSecurity: true // optional +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; +use appwrite::id::ID; +use appwrite::permission::Permission; +use appwrite::role::Role; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.create_collection( + "<DATABASE_ID>", + ID::unique(), + "documents", + 4, + Some(vec![ + Permission::read(Role::any()).to_string(), + Permission::create(Role::users(None)).to_string(), + Permission::update(Role::users(None)).to_string(), + Permission::delete(Role::users(None)).to_string(), + ]), + Some(true), // documentSecurity (optional) + None, // enabled (optional) + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite vectors-db create-collection \ + --database-id "<DATABASE_ID>" \ + --collection-id "<COLLECTION_ID>" \ + --name "documents" \ + --dimension 4 \ + --permissions 'read("any")' 'create("users")' 'update("users")' 'delete("users")' \ + --document-security true +``` +{% /multicode %} + +To change a collection's permissions later, pass a new `permissions` array to `updateCollection`. The `name` is required when updating. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.updateCollection({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + name: 'documents', + permissions: [ + sdk.Permission.read(sdk.Role.any()), + sdk.Permission.create(sdk.Role.users()) + ], + documentSecurity: false // optional +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.updateCollection({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + name: 'documents', + permissions: [ + sdk.Permission.read(sdk.Role.any()), + sdk.Permission.create(sdk.Role.users()) + ], + documentSecurity: false // optional +}); +``` +```php +<?php + +use Appwrite\Client; +use Appwrite\Services\VectorsDB; +use Appwrite\Permission; +use Appwrite\Role; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('<YOUR_PROJECT_ID>') // Your project ID + ->setKey('<YOUR_API_KEY>'); // Your secret API key + +$vectorsDB = new VectorsDB($client); + +$result = $vectorsDB->updateCollection( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + name: 'documents', + permissions: [ + Permission::read(Role::any()), + Permission::create(Role::users()) + ], + documentSecurity: false // optional +); +``` +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB +from appwrite.permission import Permission +from appwrite.role import Role + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('<YOUR_PROJECT_ID>') # Your project ID +client.set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB(client) + +result = vectors_db.update_collection( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>', + name = 'documents', + permissions = [ + Permission.read(Role.any()), + Permission.create(Role.users()) + ], + document_security = False # optional +) +``` +```ruby +require 'appwrite' + +include Appwrite +include Appwrite::Permission +include Appwrite::Role + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('<YOUR_PROJECT_ID>') # Your project ID + .set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB.new(client) + +result = vectors_db.update_collection( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + name: 'documents', + permissions: [ + Permission.read(Role.any()), + Permission.create(Role.users()) + ], + document_security: false # optional +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("<YOUR_PROJECT_ID>") // Your project ID + .SetKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +Collection result = await vectorsDB.UpdateCollection( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + name: "documents", + permissions: new List<string> { + Permission.Read(Role.Any()), + Permission.Create(Role.Users()) + }, + documentSecurity: false // optional +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; +import 'package:dart_appwrite/permission.dart'; +import 'package:dart_appwrite/role.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +VectorsDB vectorsDB = VectorsDB(client); + +Collection result = await vectorsDB.updateCollection( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + name: 'documents', + permissions: [ + Permission.read(Role.any()), + Permission.create(Role.users()) + ], // (optional) + documentSecurity: false, // (optional) +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.Permission +import io.appwrite.Role +import io.appwrite.services.VectorsDB + +val client = Client(context) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +val vectorsDB = VectorsDB(client) + +val response = vectorsDB.updateCollection( + databaseId = "<DATABASE_ID>", + collectionId = "<COLLECTION_ID>", + name = "documents", + permissions = listOf( + Permission.read(Role.any()), + Permission.create(Role.users()) + ), // optional + documentSecurity = false, // optional +) +``` +```java +import io.appwrite.Client; +import io.appwrite.Permission; +import io.appwrite.Role; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.VectorsDB; +import java.util.List; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +vectorsDB.updateCollection( + "<DATABASE_ID>", + "<COLLECTION_ID>", + "documents", + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +let vectorsDB = VectorsDB(client) + +let collection = try await vectorsDB.updateCollection( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + name: "documents", + permissions: [ + Permission.read(Role.any()), + Permission.create(Role.users()) + ], + documentSecurity: false // optional +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; +use appwrite::permission::Permission; +use appwrite::role::Role; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.update_collection( + "<DATABASE_ID>", + "<COLLECTION_ID>", + "documents", + None, // dimension (optional) + Some(vec![ + Permission::read(Role::any()).to_string(), + Permission::create(Role::users(None)).to_string(), + ]), + Some(false), // documentSecurity (optional) + None, // enabled (optional) + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite vectors-db update-collection \ + --database-id "<DATABASE_ID>" \ + --collection-id "<COLLECTION_ID>" \ + --name "documents" \ + --permissions 'read("any")' 'create("users")' \ + --document-security false +``` +{% /multicode %} + +[Learn more about permissions and roles](/docs/advanced/platform/permissions) + +# Document level {% #document-level %} +Document level permissions grant access to individual documents. +If a user has read, update, or delete permissions at the document level, the user can access the **individual document**. + +Document level permissions are only applied if `documentSecurity` is enabled on the collection. Enable it in the Console by navigating to **Your collection** > **Security** > **Document security**, or by setting `documentSecurity` to `true` when you create or update the collection, as shown above. + +Set permissions on an individual document by passing a `permissions` array to `createDocument`. Use `Role.user('<USER_ID>')` to scope access to a specific user. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.createDocument({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: sdk.ID.unique(), + data: { + embeddings: [0.12, 0.84, 0.33, 0.57], + metadata: { title: 'Hamlet' } + }, + permissions: [ + sdk.Permission.read(sdk.Role.any()), + sdk.Permission.update(sdk.Role.user('<USER_ID>')), + sdk.Permission.delete(sdk.Role.user('<USER_ID>')) + ] +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.createDocument({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: sdk.ID.unique(), + data: { + embeddings: [0.12, 0.84, 0.33, 0.57], + metadata: { title: 'Hamlet' } + }, + permissions: [ + sdk.Permission.read(sdk.Role.any()), + sdk.Permission.update(sdk.Role.user('<USER_ID>')), + sdk.Permission.delete(sdk.Role.user('<USER_ID>')) + ] +}); +``` +```php +<?php + +use Appwrite\Client; +use Appwrite\Services\VectorsDB; +use Appwrite\ID; +use Appwrite\Permission; +use Appwrite\Role; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('<YOUR_PROJECT_ID>') // Your project ID + ->setKey('<YOUR_API_KEY>'); // Your secret API key + +$vectorsDB = new VectorsDB($client); + +$result = $vectorsDB->createDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: ID::unique(), + data: [ + 'embeddings' => [0.12, 0.84, 0.33, 0.57], + 'metadata' => ['title' => 'Hamlet'] + ], + permissions: [ + Permission::read(Role::any()), + Permission::update(Role::user('<USER_ID>')), + Permission::delete(Role::user('<USER_ID>')) + ] +); +``` +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB +from appwrite.id import ID +from appwrite.permission import Permission +from appwrite.role import Role + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('<YOUR_PROJECT_ID>') # Your project ID +client.set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB(client) + +result = vectors_db.create_document( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>', + document_id = ID.unique(), + data = { + "embeddings": [0.12, 0.84, 0.33, 0.57], + "metadata": { "title": "Hamlet" } + }, + permissions = [ + Permission.read(Role.any()), + Permission.update(Role.user('<USER_ID>')), + Permission.delete(Role.user('<USER_ID>')) + ] +) +``` +```ruby +require 'appwrite' + +include Appwrite +include Appwrite::Permission +include Appwrite::Role + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('<YOUR_PROJECT_ID>') # Your project ID + .set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB.new(client) + +result = vectors_db.create_document( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + document_id: ID.unique(), + data: { + "embeddings" => [0.12, 0.84, 0.33, 0.57], + "metadata" => { "title" => "Hamlet" } + }, + permissions: [ + Permission.read(Role.any()), + Permission.update(Role.user('<USER_ID>')), + Permission.delete(Role.user('<USER_ID>')) + ] +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("<YOUR_PROJECT_ID>") // Your project ID + .SetKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +Document result = await vectorsDB.CreateDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: ID.Unique(), + data: new Dictionary<string, object> { + { "embeddings", new List<double> { 0.12, 0.84, 0.33, 0.57 } }, + { "metadata", new Dictionary<string, object> { { "title", "Hamlet" } } } + }, + permissions: new List<string> { + Permission.Read(Role.Any()), + Permission.Update(Role.User("<USER_ID>")), + Permission.Delete(Role.User("<USER_ID>")) + } +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; +import 'package:dart_appwrite/permission.dart'; +import 'package:dart_appwrite/role.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +VectorsDB vectorsDB = VectorsDB(client); + +Document result = await vectorsDB.createDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: ID.unique(), + data: { + "embeddings": [0.12, 0.84, 0.33, 0.57], + "metadata": { "title": "Hamlet" } + }, + permissions: [ + Permission.read(Role.any()), + Permission.update(Role.user('<USER_ID>')), + Permission.delete(Role.user('<USER_ID>')) + ], // (optional) +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.ID +import io.appwrite.Permission +import io.appwrite.Role +import io.appwrite.services.VectorsDB + +val client = Client(context) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +val vectorsDB = VectorsDB(client) + +val response = vectorsDB.createDocument( + databaseId = "<DATABASE_ID>", + collectionId = "<COLLECTION_ID>", + documentId = ID.unique(), + data = mapOf( + "embeddings" to listOf(0.12, 0.84, 0.33, 0.57), + "metadata" to mapOf("title" to "Hamlet") + ), + permissions = listOf( + Permission.read(Role.any()), + Permission.update(Role.user("<USER_ID>")), + Permission.delete(Role.user("<USER_ID>")) + ), // optional +) +``` +```java +import io.appwrite.Client; +import io.appwrite.ID; +import io.appwrite.Permission; +import io.appwrite.Role; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.VectorsDB; +import java.util.List; +import java.util.Map; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +vectorsDB.createDocument( + "<DATABASE_ID>", + "<COLLECTION_ID>", + ID.unique(), + Map.of( + "embeddings", List.of(0.12, 0.84, 0.33, 0.57), + "metadata", Map.of("title", "Hamlet") + ), + List.of( + Permission.read(Role.any()), + Permission.update(Role.user("<USER_ID>")), + Permission.delete(Role.user("<USER_ID>")) + ), + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +let vectorsDB = VectorsDB(client) + +let document = try await vectorsDB.createDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: ID.unique(), + data: [ + "embeddings": [0.12, 0.84, 0.33, 0.57], + "metadata": ["title": "Hamlet"] + ], + permissions: [ + Permission.read(Role.any()), + Permission.update(Role.user("<USER_ID>")), + Permission.delete(Role.user("<USER_ID>")) + ] +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; +use appwrite::id::ID; +use appwrite::permission::Permission; +use appwrite::role::Role; +use serde_json::json; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.create_document( + "<DATABASE_ID>", + "<COLLECTION_ID>", + ID::unique(), + json!({ + "embeddings": [0.12, 0.84, 0.33, 0.57], + "metadata": { "title": "Hamlet" } + }), + Some(vec![ + Permission::read(Role::any()).to_string(), + Permission::update(Role::user("<USER_ID>", None)).to_string(), + Permission::delete(Role::user("<USER_ID>", None)).to_string(), + ]), + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite vectors-db create-document \ + --database-id "<DATABASE_ID>" \ + --collection-id "<COLLECTION_ID>" \ + --document-id 'unique()' \ + --data '{ "embeddings": [0.12, 0.84, 0.33, 0.57], "metadata": { "title": "Hamlet" } }' \ + --permissions 'read("any")' 'update("user:<USER_ID>")' 'delete("user:<USER_ID>")' +``` +{% /multicode %} + +To change a document's permissions later, pass a new `permissions` array to `updateDocument`. Only the fields you pass are changed, so you can update permissions without touching the vector or metadata. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.updateDocument({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + permissions: [ + sdk.Permission.read(sdk.Role.users()) + ] +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.updateDocument({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + permissions: [ + sdk.Permission.read(sdk.Role.users()) + ] +}); +``` +```php +<?php + +use Appwrite\Client; +use Appwrite\Services\VectorsDB; +use Appwrite\Permission; +use Appwrite\Role; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('<YOUR_PROJECT_ID>') // Your project ID + ->setKey('<YOUR_API_KEY>'); // Your secret API key + +$vectorsDB = new VectorsDB($client); + +$result = $vectorsDB->updateDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + permissions: [ + Permission::read(Role::users()) + ] +); +``` +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB +from appwrite.permission import Permission +from appwrite.role import Role + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('<YOUR_PROJECT_ID>') # Your project ID +client.set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB(client) + +result = vectors_db.update_document( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>', + document_id = '<DOCUMENT_ID>', + permissions = [ + Permission.read(Role.users()) + ] +) +``` +```ruby +require 'appwrite' + +include Appwrite +include Appwrite::Permission +include Appwrite::Role + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('<YOUR_PROJECT_ID>') # Your project ID + .set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB.new(client) + +result = vectors_db.update_document( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + document_id: '<DOCUMENT_ID>', + permissions: [ + Permission.read(Role.users()) + ] +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("<YOUR_PROJECT_ID>") // Your project ID + .SetKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +Document result = await vectorsDB.UpdateDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: "<DOCUMENT_ID>", + permissions: new List<string> { + Permission.Read(Role.Users()) + } +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; +import 'package:dart_appwrite/permission.dart'; +import 'package:dart_appwrite/role.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +VectorsDB vectorsDB = VectorsDB(client); + +Document result = await vectorsDB.updateDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + permissions: [ + Permission.read(Role.users()) + ], // (optional) +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.Permission +import io.appwrite.Role +import io.appwrite.services.VectorsDB + +val client = Client(context) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +val vectorsDB = VectorsDB(client) + +val response = vectorsDB.updateDocument( + databaseId = "<DATABASE_ID>", + collectionId = "<COLLECTION_ID>", + documentId = "<DOCUMENT_ID>", + permissions = listOf( + Permission.read(Role.users()) + ), // optional +) +``` +```java +import io.appwrite.Client; +import io.appwrite.Permission; +import io.appwrite.Role; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.VectorsDB; +import java.util.List; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +vectorsDB.updateDocument( + "<DATABASE_ID>", + "<COLLECTION_ID>", + "<DOCUMENT_ID>", + null, + List.of( + Permission.read(Role.users()) + ), + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +let vectorsDB = VectorsDB(client) + +let document = try await vectorsDB.updateDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: "<DOCUMENT_ID>", + permissions: [ + Permission.read(Role.users()) + ] +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; +use appwrite::permission::Permission; +use appwrite::role::Role; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.update_document( + "<DATABASE_ID>", + "<COLLECTION_ID>", + "<DOCUMENT_ID>", + None, // data (optional) + Some(vec![ + Permission::read(Role::users(None)).to_string(), + ]), + None, // transactionId (optional) + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite vectors-db update-document \ + --database-id "<DATABASE_ID>" \ + --collection-id "<COLLECTION_ID>" \ + --document-id "<DOCUMENT_ID>" \ + --permissions 'read("users")' +``` +{% /multicode %} + +[Learn more about permissions and roles](/docs/advanced/platform/permissions) + +# Common use cases {% #common-use-cases %} + +For examples of how to implement common permission patterns, including creating private documents that are only accessible to their creators, see the [permissions examples](/docs/advanced/platform/permissions#examples) in our platform documentation. diff --git a/src/routes/docs/products/databases/vectorsdb/queries/+page.markdoc b/src/routes/docs/products/databases/vectorsdb/queries/+page.markdoc new file mode 100644 index 00000000000..5e36bec2324 --- /dev/null +++ b/src/routes/docs/products/databases/vectorsdb/queries/+page.markdoc @@ -0,0 +1,1879 @@ +--- +layout: article +title: Queries +description: Filter VectorsDB documents by their metadata using the Query class. Discover comparison, string, logical, ordering, and pagination operators. +--- + +Many list endpoints in Appwrite allow you to filter, sort, and paginate results using queries. Appwrite provides a common set of syntax to build queries. + +In VectorsDB, every document stores an `embeddings` vector and an optional `metadata` object. The queries on this page filter documents by the fields inside that `metadata` object. To rank documents by vector similarity instead, see [vector search](/docs/products/databases/vectorsdb/vector-search). + +# Query class {% #query-class %} + +Appwrite SDKs provide a `Query` class to help you build queries. The `Query` class has methods for each type of supported query operation. + +# Building queries {% #building-queries %} + +Queries are passed to an endpoint through the `queries` parameter as an array of query strings, which can be generated using the `Query` class. + +Each query method is logically separated via `AND` operations. For `OR` operation, pass multiple values into the query method separated by commas. +For example `Query.equal('metadata.genre', ['sci-fi', 'drama'])` will fetch documents whose genre is `sci-fi` or `drama`. + +To filter on a field inside the `metadata` object, reference it with dot notation, such as `metadata.genre` or `metadata.year`. + +{% info title="Filter metadata with string values" %} +VectorsDB stores `metadata` as a JSON object, so metadata fields are compared as strings. Pass filter values as strings, even when the stored value is a number. For example, use `Query.greaterThan('metadata.year', '2010')`, not `Query.greaterThan('metadata.year', 2010)`. Passing a numeric value returns a `400` error. +{% /info %} + +{% info title="Default pagination behavior" %} +By default, results are limited to the **first 25 items**. +You can change this through [pagination](/docs/products/databases/vectorsdb/pagination). +{% /info %} + +{% multicode %} + +```client-web +import { Client, Query, VectorsDB } from "appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>'); + +const vectorsDB = new VectorsDB(client); + +vectorsDB.listDocuments({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + Query.equal('metadata.genre', ['sci-fi', 'drama']), + Query.greaterThan('metadata.year', '2010') + ] +}); +``` +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client(); + +const vectorsDB = new sdk.VectorsDB(client); + +client + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>') +; + +const promise = vectorsDB.listDocuments({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + sdk.Query.equal('metadata.genre', ['sci-fi', 'drama']), + sdk.Query.greaterThan('metadata.year', '2010') + ] +}); + +promise.then(function (response) { + console.log(response); +}, function (error) { + console.log(error); +}); +``` +```client-flutter +import 'package:appwrite/appwrite.dart'; + +void main() async { + final client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>'); + + final vectorsDB = VectorsDB(client); + + try { + final documents = await vectorsDB.listDocuments( + '<DATABASE_ID>', + '<COLLECTION_ID>', + [ + Query.equal('metadata.genre', ['sci-fi', 'drama']), + Query.greaterThan('metadata.year', '2010') + ] + ); + } on AppwriteException catch(e) { + print(e); + } +} +``` +```client-apple +import Appwrite +import AppwriteModels + +func main() async throws { + let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + + let vectorsDB = VectorsDB(client) + + do { + let documents = try await vectorsDB.listDocuments( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + queries: [ + Query.equal("metadata.genre", value: ["sci-fi", "drama"]), + Query.greaterThan("metadata.year", value: "2010") + ] + ) + } catch { + print(error.localizedDescription) + } +} +``` +```client-android-kotlin +import io.appwrite.Client +import io.appwrite.Query +import io.appwrite.services.VectorsDB + +suspend fun main() { + val client = Client(applicationContext) + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>'); + + val vectorsDB = VectorsDB(client) + + try { + val documents = vectorsDB.listDocuments( + databaseId = "<DATABASE_ID>", + collectionId = "<COLLECTION_ID>", + queries = listOf( + Query.equal("metadata.genre", listOf("sci-fi", "drama")), + Query.greaterThan("metadata.year", "2010") + ) + ) + } catch (e: AppwriteException) { + Log.e("Appwrite", e.message) + } +} +``` +```server-go +package main + +import ( + "fmt" + "log" + + "github.com/appwrite/sdk-for-go/appwrite" + "github.com/appwrite/sdk-for-go/query" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<API_KEY>"), + ) + + vectorsDB := appwrite.NewVectorsDB(client) + + documents, err := vectorsDB.ListDocuments( + "<DATABASE_ID>", + "<COLLECTION_ID>", + vectorsDB.WithListDocumentsQueries([]string{ + query.Equal("metadata.genre", []string{"sci-fi", "drama"}), + query.GreaterThan("metadata.year", "2010"), + }), + ) + if err != nil { + log.Fatal(err) + } + + fmt.Printf("Documents: %+v\n", documents) +} +``` +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; +use appwrite::query::Query; +use serde_json::Value; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let vectors_db = VectorsDB::new(&client); + + let documents = vectors_db.list_documents( + "<DATABASE_ID>", + "<COLLECTION_ID>", + Some(vec![ + Query::equal("metadata.genre", Value::Array(vec![ + Value::String("sci-fi".to_string()), + Value::String("drama".to_string()), + ])).to_string(), + Query::greater_than("metadata.year", "2010").to_string(), + ]), + None, + None, + None, + ).await?; + + println!("{:?}", documents); + Ok(()) +} +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Query; +use Appwrite\Services\VectorsDB; + +$client = new Client(); + +$client + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>') +; + +$vectorsDB = new VectorsDB($client); + +$result = $vectorsDB->listDocuments( + '<DATABASE_ID>', + '<COLLECTION_ID>', + [ + Query::equal('metadata.genre', ['sci-fi', 'drama']), + Query::greaterThan('metadata.year', '2010') + ] +); +``` +```server-python +from appwrite.client import Client +from appwrite.query import Query +from appwrite.services.vectors_db import VectorsDB + +client = Client() + +(client + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') +) + +vectorsDB = VectorsDB(client) + +result = vectorsDB.list_documents( + '<DATABASE_ID>', + '<COLLECTION_ID>', + [ + Query.equal('metadata.genre', ['sci-fi', 'drama']), + Query.greater_than('metadata.year', '2010') + ] +) +``` +```graphql +query { + vectorsDBListDocuments( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>" + queries: [ + "{\"method\":\"equal\",\"attribute\":\"metadata.genre\",\"values\":[\"sci-fi\",\"drama\"]}", + "{\"method\":\"greaterThan\",\"attribute\":\"metadata.year\",\"values\":[\"2010\"]}" + ] + ) { + total + documents { + _id + data + } + } +} +``` +```http +GET /v1/vectorsdb/<DATABASE_ID>/collections/<COLLECTION_ID>/documents?queries[]=%7B%22method%22%3A%22equal%22%2C%22attribute%22%3A%22metadata.genre%22%2C%22values%22%3A%5B%22sci-fi%22%2C%22drama%22%5D%7D&queries[]=%7B%22method%22%3A%22greaterThan%22%2C%22attribute%22%3A%22metadata.year%22%2C%22values%22%3A%5B%222010%22%5D%7D HTTP/1.1 +Content-Type: application/json +X-Appwrite-Project: <PROJECT_ID> +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"equal","attribute":"metadata.genre","values":["sci-fi","drama"]}' '{"method":"greaterThan","attribute":"metadata.year","values":["2010"]}' +``` +{% /multicode %} + +# Query operators {% #query-operators %} + +## Select {% #select %} + +The `select` operator allows you to specify which fields should be returned from a document. This optimizes response size and retrieves only the data you need. Each VectorsDB document has two data fields, `embeddings` and `metadata`. + +{% multicode %} +```client-web +Query.select(["metadata"]) +``` +```client-flutter +Query.select(["metadata"]) +``` +```server-python +Query.select(["metadata"]) +``` +```server-ruby +Query.select(["metadata"]) +``` +```server-deno +Query.select(["metadata"]) +``` +```server-php +Query::select(["metadata"]) +``` +```client-apple +Query.select(["metadata"]) +``` +```server-go +query.Select([]string{"metadata"}) +``` +```server-nodejs +Query.select(["metadata"]) +``` +```server-rust +Query::select(vec!["metadata"]).to_string() +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"select","values":["metadata"]}' +``` +```http +{"method":"select","values":["metadata"]} +``` +{% /multicode %} + +### Use selection patterns {% #select-patterns %} + +| Pattern | Description | Use case | +|---------|-------------|----------| +| `["metadata"]` | Metadata object only | Return metadata without the embedding vector | +| `["embeddings"]` | Embedding vector only | Return the stored vector | +| `["metadata", "embeddings"]` | Both data fields | Get the complete document data | + +### Optimize performance {% #select-performance %} + +**Optimize response size** - Only select the fields you actually need. Embedding vectors are large, so omitting `embeddings` keeps responses small when you only need metadata. + +**Reduce database load** - Selecting fewer fields reduces database processing time. + +## Comparison operators {% #comparison %} + +Pass metadata filter values as strings. See [Filter metadata with string values](#building-queries). + +### Equal {% #equal %} + +Returns document if a metadata field is equal to any value in the provided array. + +{% multicode %} +```client-web +Query.equal("metadata.genre", ["sci-fi"]) +``` +```client-flutter +Query.equal("metadata.genre", ["sci-fi"]) +``` +```server-python +Query.equal("metadata.genre", ["sci-fi"]) +``` +```server-ruby +Query.equal("metadata.genre", ["sci-fi"]) +``` +```server-deno +Query.equal("metadata.genre", ["sci-fi"]) +``` +```server-php +Query::equal("metadata.genre", ["sci-fi"]) +``` +```client-apple +Query.equal("metadata.genre", value: ["sci-fi"]) +``` +```server-go +query.Equal("metadata.genre", []string{"sci-fi"}) +``` +```server-nodejs +Query.equal("metadata.genre", ["sci-fi"]) +``` +```server-rust +Query::equal("metadata.genre", Value::Array(vec![Value::String("sci-fi".to_string())])).to_string() +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"equal","attribute":"metadata.genre","values":["sci-fi"]}' +``` +```http +{"method":"equal","attribute":"metadata.genre","values":["sci-fi"]} +``` +{% /multicode %} + +### Not equal {% #not-equal %} + +Returns document if a metadata field is not equal to the provided value. + +{% multicode %} +```client-web +Query.notEqual("metadata.genre", "sci-fi") +``` +```client-flutter +Query.notEqual("metadata.genre", "sci-fi") +``` +```server-python +Query.not_equal("metadata.genre", "sci-fi") +``` +```server-ruby +Query.not_equal("metadata.genre", "sci-fi") +``` +```server-deno +Query.notEqual("metadata.genre", "sci-fi") +``` +```server-php +Query::notEqual("metadata.genre", "sci-fi") +``` +```client-apple +Query.notEqual("metadata.genre", value: "sci-fi") +``` +```server-go +query.NotEqual("metadata.genre", "sci-fi") +``` +```server-nodejs +Query.notEqual("metadata.genre", "sci-fi") +``` +```server-rust +Query::not_equal("metadata.genre", "sci-fi").to_string() +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"notEqual","attribute":"metadata.genre","values":["sci-fi"]}' +``` +```http +{"method":"notEqual","attribute":"metadata.genre","values":"sci-fi"} +``` +{% /multicode %} + +### Less than {% #less-than %} + +Returns document if a metadata field is less than the provided value. + +{% multicode %} +```client-web +Query.lessThan("metadata.year", "2009") +``` +```client-flutter +Query.lessThan("metadata.year", "2009") +``` +```server-python +Query.less_than("metadata.year", "2009") +``` +```server-ruby +Query.less_than("metadata.year", "2009") +``` +```server-deno +Query.lessThan("metadata.year", "2009") +``` +```server-php +Query::lessThan("metadata.year", "2009") +``` +```client-apple +Query.lessThan("metadata.year", value: "2009") +``` +```server-go +query.LessThan("metadata.year", "2009") +``` +```server-nodejs +Query.lessThan("metadata.year", "2009") +``` +```server-rust +Query::less_than("metadata.year", "2009").to_string() +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"lessThan","attribute":"metadata.year","values":["2009"]}' +``` +```http +{"method":"lessThan","attribute":"metadata.year","values":["2009"]} +``` +{% /multicode %} + +### Less than or equal {% #less-than-equal %} + +Returns document if a metadata field is less than or equal to the provided value. + +{% multicode %} +```client-web +Query.lessThanEqual("metadata.year", "2009") +``` +```client-flutter +Query.lessThanEqual("metadata.year", "2009") +``` +```server-python +Query.less_than_equal("metadata.year", "2009") +``` +```server-ruby +Query.less_than_equal("metadata.year", "2009") +``` +```server-deno +Query.lessThanEqual("metadata.year", "2009") +``` +```server-php +Query::lessThanEqual("metadata.year", "2009") +``` +```client-apple +Query.lessThanEqual("metadata.year", value: "2009") +``` +```server-go +query.LessThanEqual("metadata.year", "2009") +``` +```server-nodejs +Query.lessThanEqual("metadata.year", "2009") +``` +```server-rust +Query::less_than_equal("metadata.year", "2009").to_string() +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"lessThanEqual","attribute":"metadata.year","values":["2009"]}' +``` +```http +{"method":"lessThanEqual","attribute":"metadata.year","values":["2009"]} +``` +{% /multicode %} + +### Greater than {% #greater-than %} + +Returns document if a metadata field is greater than the provided value. + +{% multicode %} +```client-web +Query.greaterThan("metadata.year", "2009") +``` +```client-flutter +Query.greaterThan("metadata.year", "2009") +``` +```server-python +Query.greater_than("metadata.year", "2009") +``` +```server-ruby +Query.greater_than("metadata.year", "2009") +``` +```server-deno +Query.greaterThan("metadata.year", "2009") +``` +```server-php +Query::greaterThan("metadata.year", "2009") +``` +```client-apple +Query.greaterThan("metadata.year", value: "2009") +``` +```server-go +query.GreaterThan("metadata.year", "2009") +``` +```server-nodejs +Query.greaterThan("metadata.year", "2009") +``` +```server-rust +Query::greater_than("metadata.year", "2009").to_string() +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"greaterThan","attribute":"metadata.year","values":["2009"]}' +``` +```http +{"method":"greaterThan","attribute":"metadata.year","values":["2009"]} +``` +{% /multicode %} + +### Greater than or equal {% #greater-than-equal %} + +Returns document if a metadata field is greater than or equal to the provided value. + +{% multicode %} +```client-web +Query.greaterThanEqual("metadata.year", "2009") +``` +```client-flutter +Query.greaterThanEqual("metadata.year", "2009") +``` +```server-python +Query.greater_than_equal("metadata.year", "2009") +``` +```server-ruby +Query.greater_than_equal("metadata.year", "2009") +``` +```server-deno +Query.greaterThanEqual("metadata.year", "2009") +``` +```server-php +Query::greaterThanEqual("metadata.year", "2009") +``` +```client-apple +Query.greaterThanEqual("metadata.year", value: "2009") +``` +```server-go +query.GreaterThanEqual("metadata.year", "2009") +``` +```server-nodejs +Query.greaterThanEqual("metadata.year", "2009") +``` +```server-rust +Query::greater_than_equal("metadata.year", "2009").to_string() +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"greaterThanEqual","attribute":"metadata.year","values":["2009"]}' +``` +```http +{"method":"greaterThanEqual","attribute":"metadata.year","values":["2009"]} +``` +{% /multicode %} + +### Between {% #between %} + +Returns document if a metadata field value falls between the two values. The boundary values are inclusive. + +{% multicode %} +```client-web +Query.between("metadata.year", "2005", "2010") +``` +```client-flutter +Query.between("metadata.year", "2005", "2010") +``` +```server-python +Query.between("metadata.year", "2005", "2010") +``` +```server-ruby +Query.between("metadata.year", "2005", "2010") +``` +```server-deno +Query.between("metadata.year", "2005", "2010") +``` +```server-php +Query::between("metadata.year", "2005", "2010") +``` +```client-apple +Query.between("metadata.year", start: "2005", end: "2010") +``` +```server-go +query.Between("metadata.year", "2005", "2010") +``` +```server-nodejs +Query.between("metadata.year", "2005", "2010") +``` +```server-rust +Query::between("metadata.year", "2005", "2010").to_string() +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"between","attribute":"metadata.year","values":["2005","2010"]}' +``` +```http +{"method":"between","attribute":"metadata.year","values":["2005","2010"]} +``` +{% /multicode %} + +### Not between {% #not-between %} + +Returns documents if the metadata field value is outside the range defined by the two values. Boundary values are excluded. + +{% multicode %} +```client-web +Query.notBetween("metadata.year", "2005", "2010") +``` +```client-flutter +Query.notBetween("metadata.year", "2005", "2010") +``` +```client-apple +Query.notBetween("metadata.year", start: "2005", end: "2010") +``` +```client-android-kotlin +Query.notBetween("metadata.year", "2005", "2010") +``` +```client-android-java +Query.notBetween("metadata.year", "2005", "2010") +``` +```server-python +Query.not_between("metadata.year", "2005", "2010") +``` +```server-ruby +Query.not_between("metadata.year", "2005", "2010") +``` +```server-deno +Query.notBetween("metadata.year", "2005", "2010") +``` +```server-nodejs +Query.notBetween("metadata.year", "2005", "2010") +``` +```server-php +Query::notBetween("metadata.year", "2005", "2010") +``` +```server-swift +Query.notBetween("metadata.year", start: "2005", end: "2010") +``` +```server-rust +Query::not_between("metadata.year", "2005", "2010").to_string() +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"notBetween","attribute":"metadata.year","values":["2005","2010"]}' +``` +```http +{"method":"notBetween","attribute":"metadata.year","values":["2005","2010"]} +``` +{% /multicode %} + +## Null checks {% #null-checks %} + +### Is null {% #is-null %} + +Returns documents where the metadata field value is null or absent. + +{% multicode %} +```client-web +Query.isNull("metadata.archived") +``` +```client-flutter +Query.isNull("metadata.archived") +``` +```server-python +Query.is_null("metadata.archived") +``` +```server-ruby +Query.is_null("metadata.archived") +``` +```server-deno +Query.isNull("metadata.archived") +``` +```server-php +Query::isNull("metadata.archived") +``` +```client-apple +Query.isNull("metadata.archived") +``` +```server-go +query.IsNull("metadata.archived") +``` +```server-nodejs +Query.isNull("metadata.archived") +``` +```server-rust +Query::is_null("metadata.archived").to_string() +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"isNull","attribute":"metadata.archived"}' +``` +```http +{"method":"isNull","attribute":"metadata.archived"} +``` +{% /multicode %} + +### Is not null {% #is-not-null %} + +Returns documents where the metadata field value is **not** null. + +{% multicode %} +```client-web +Query.isNotNull("metadata.archived") +``` +```client-flutter +Query.isNotNull("metadata.archived") +``` +```server-python +Query.is_not_null("metadata.archived") +``` +```server-ruby +Query.is_not_null("metadata.archived") +``` +```server-deno +Query.isNotNull("metadata.archived") +``` +```server-php +Query::isNotNull("metadata.archived") +``` +```client-apple +Query.isNotNull("metadata.archived") +``` +```server-go +query.IsNotNull("metadata.archived") +``` +```server-nodejs +Query.isNotNull("metadata.archived") +``` +```server-rust +Query::is_not_null("metadata.archived").to_string() +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"isNotNull","attribute":"metadata.archived"}' +``` +```http +{"method":"isNotNull","attribute":"metadata.archived"} +``` +{% /multicode %} + +## String operations {% #string-operations %} + +### Starts with {% #starts-with %} + +Returns documents if a metadata string field starts with a substring. + +{% multicode %} +```client-web +Query.startsWith("metadata.title", "Iron") +``` +```client-flutter +Query.startsWith("metadata.title", "Iron") +``` +```server-python +Query.starts_with("metadata.title", "Iron") +``` +```server-ruby +Query.starts_with("metadata.title", "Iron") +``` +```server-deno +Query.startsWith("metadata.title", "Iron") +``` +```server-php +Query::startsWith("metadata.title", "Iron") +``` +```client-apple +Query.startsWith("metadata.title", value: "Iron") +``` +```server-go +query.StartsWith("metadata.title", "Iron") +``` +```server-nodejs +Query.startsWith("metadata.title", "Iron") +``` +```server-rust +Query::starts_with("metadata.title", "Iron").to_string() +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"startsWith","attribute":"metadata.title","values":["Iron"]}' +``` +```http +{"method":"startsWith","attribute":"metadata.title","values":["Iron"]} +``` +{% /multicode %} + +### Not starts with {% #not-starts-with %} + +Returns documents if a metadata string field does not start with a substring. + +{% multicode %} +```client-web +Query.notStartsWith("metadata.title", "Iron") +``` +```client-flutter +Query.notStartsWith("metadata.title", "Iron") +``` +```client-apple +Query.notStartsWith("metadata.title", value: "Iron") +``` +```client-android-kotlin +Query.notStartsWith("metadata.title", "Iron") +``` +```client-android-java +Query.notStartsWith("metadata.title", "Iron") +``` +```server-python +Query.not_starts_with("metadata.title", "Iron") +``` +```server-ruby +Query.not_starts_with("metadata.title", "Iron") +``` +```server-deno +Query.notStartsWith("metadata.title", "Iron") +``` +```server-nodejs +Query.notStartsWith("metadata.title", "Iron") +``` +```server-php +Query::notStartsWith("metadata.title", "Iron") +``` +```server-swift +Query.notStartsWith("metadata.title", value: "Iron") +``` +```server-rust +Query::not_starts_with("metadata.title", "Iron").to_string() +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"notStartsWith","attribute":"metadata.title","values":["Iron"]}' +``` +```http +{"method":"notStartsWith","attribute":"metadata.title","values":["Iron"]} +``` +{% /multicode %} + +### Ends with {% #ends-with %} + +Returns documents if a metadata string field ends with a substring. + +{% multicode %} +```client-web +Query.endsWith("metadata.title", "Man") +``` +```client-flutter +Query.endsWith("metadata.title", "Man") +``` +```server-python +Query.ends_with("metadata.title", "Man") +``` +```server-ruby +Query.ends_with("metadata.title", "Man") +``` +```server-deno +Query.endsWith("metadata.title", "Man") +``` +```server-php +Query::endsWith("metadata.title", "Man") +``` +```client-apple +Query.endsWith("metadata.title", value: "Man") +``` +```server-go +query.EndsWith("metadata.title", "Man") +``` +```server-nodejs +Query.endsWith("metadata.title", "Man") +``` +```server-rust +Query::ends_with("metadata.title", "Man").to_string() +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"endsWith","attribute":"metadata.title","values":["Man"]}' +``` +```http +{"method":"endsWith","attribute":"metadata.title","values":["Man"]} +``` +{% /multicode %} + +### Not ends with {% #not-ends-with %} + +Returns documents if a metadata string field does not end with a substring. + +{% multicode %} +```client-web +Query.notEndsWith("metadata.title", "Man") +``` +```client-flutter +Query.notEndsWith("metadata.title", "Man") +``` +```client-apple +Query.notEndsWith("metadata.title", value: "Man") +``` +```client-android-kotlin +Query.notEndsWith("metadata.title", "Man") +``` +```client-android-java +Query.notEndsWith("metadata.title", "Man") +``` +```server-python +Query.not_ends_with("metadata.title", "Man") +``` +```server-ruby +Query.not_ends_with("metadata.title", "Man") +``` +```server-deno +Query.notEndsWith("metadata.title", "Man") +``` +```server-nodejs +Query.notEndsWith("metadata.title", "Man") +``` +```server-php +Query::notEndsWith("metadata.title", "Man") +``` +```server-swift +Query.notEndsWith("metadata.title", value: "Man") +``` +```server-rust +Query::not_ends_with("metadata.title", "Man").to_string() +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"notEndsWith","attribute":"metadata.title","values":["Man"]}' +``` +```http +{"method":"notEndsWith","attribute":"metadata.title","values":["Man"]} +``` +{% /multicode %} + +### Contains {% #contains %} + +Returns documents if a metadata array field contains the specified elements or if a metadata string field contains the specified substring. + +{% multicode %} +```client-web +// For arrays +Query.contains("metadata.tags", ["space"]) + +// For strings +Query.contains("metadata.title", "Iron") +``` +```client-flutter +// For arrays +Query.contains("metadata.tags", ["space"]) + +// For strings +Query.contains("metadata.title", "Iron") +``` +```server-python +# For arrays +Query.contains("metadata.tags", ["space"]) + +# For strings +Query.contains("metadata.title", "Iron") +``` +```server-ruby +# For arrays +Query.contains("metadata.tags", ["space"]) + +# For strings +Query.contains("metadata.title", "Iron") +``` +```server-deno +// For arrays +Query.contains("metadata.tags", ["space"]) + +// For strings +Query.contains("metadata.title", "Iron") +``` +```server-php +// For arrays +Query::contains("metadata.tags", ["space"]) + +// For strings +Query::contains("metadata.title", "Iron") +``` +```client-apple +// For arrays +Query.contains("metadata.tags", value: ["space"]) + +// For strings +Query.contains("metadata.title", value: "Iron") +``` +```server-go +// For arrays +query.Contains("metadata.tags", []string{"space"}) + +// For strings +query.Contains("metadata.title", "Iron") +``` +```server-nodejs +// For arrays +Query.contains("metadata.tags", ["space"]) + +// For strings +Query.contains("metadata.title", "Iron") +``` +```server-rust +// For arrays +Query::contains("metadata.tags", Value::Array(vec![ + Value::String("space".to_string()), +])).to_string() + +// For strings +Query::contains("metadata.title", "Iron").to_string() +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"contains","attribute":"metadata.tags","values":["space"]}' +``` +```http +# For arrays +{"method":"contains","attribute":"metadata.tags","values":["space"]} + +# For strings +{"method":"contains","attribute":"metadata.title","values":["Iron"]} +``` +{% /multicode %} + +### Not contains {% #not-contains %} + +Returns documents if a metadata array field does not contain the specified elements, or if a metadata string field does not contain the specified substring. + +{% multicode %} +```client-web +// For arrays +Query.notContains("metadata.tags", ["space"]) + +// For strings +Query.notContains("metadata.title", "Iron") +``` +```client-flutter +// For arrays +Query.notContains("metadata.tags", ["space"]) + +// For strings +Query.notContains("metadata.title", "Iron") +``` +```client-react-native +// For arrays +Query.notContains("metadata.tags", ["space"]) + +// For strings +Query.notContains("metadata.title", "Iron") +``` +```client-apple +// For arrays +Query.notContains("metadata.tags", value: ["space"]) + +// For strings +Query.notContains("metadata.title", value: "Iron") +``` +```client-android-kotlin +// For arrays +Query.notContains("metadata.tags", listOf("space")) + +// For strings +Query.notContains("metadata.title", "Iron") +``` +```client-android-java +// For arrays +Query.notContains("metadata.tags", Arrays.asList("space")) + +// For strings +Query.notContains("metadata.title", "Iron") +``` +```server-python +# For arrays +Query.not_contains("metadata.tags", ["space"]) + +# For strings +Query.not_contains("metadata.title", "Iron") +``` +```server-ruby +# For arrays +Query.not_contains("metadata.tags", ["space"]) + +# For strings +Query.not_contains("metadata.title", "Iron") +``` +```server-deno +// For arrays +Query.notContains("metadata.tags", ["space"]) + +// For strings +Query.notContains("metadata.title", "Iron") +``` +```server-nodejs +// For arrays +Query.notContains("metadata.tags", ["space"]) + +// For strings +Query.notContains("metadata.title", "Iron") +``` +```server-php +// For arrays +Query::notContains("metadata.tags", ["space"]) + +// For strings +Query::notContains("metadata.title", "Iron") +``` +```server-dotnet +// For arrays +Query.NotContains("metadata.tags", new List<string> { "space" }) + +// For strings +Query.NotContains("metadata.title", "Iron") +``` +```server-go +// For arrays +query.NotContains("metadata.tags", []string{"space"}) + +// For strings +query.NotContains("metadata.title", "Iron") +``` +```server-dart +// For arrays +Query.notContains("metadata.tags", ["space"]) + +// For strings +Query.notContains("metadata.title", "Iron") +``` +```server-swift +// For arrays +Query.notContains("metadata.tags", value: ["space"]) + +// For strings +Query.notContains("metadata.title", value: "Iron") +``` +```server-kotlin +// For arrays +Query.notContains("metadata.tags", listOf("space")) + +// For strings +Query.notContains("metadata.title", "Iron") +``` +```server-rust +// For arrays +Query::not_contains("metadata.tags", Value::Array(vec![ + Value::String("space".to_string()), +])).to_string() + +// For strings +Query::not_contains("metadata.title", "Iron").to_string() +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"notContains","attribute":"metadata.tags","values":["space"]}' +``` +```http +# For arrays +{"method":"notContains","attribute":"metadata.tags","values":["space"]} + +# For strings +{"method":"notContains","attribute":"metadata.title","values":["Iron"]} +``` +{% /multicode %} + +## Logical operators {% #logical-operators %} + +### AND {% #and %} + +Returns document if it matches all of the nested sub-queries in the array passed in. + +{% multicode %} +```client-web +Query.and([ + Query.equal("metadata.genre", "sci-fi"), + Query.startsWith("metadata.title", "Inter") +]) +``` +```client-flutter +Query.and([ + Query.equal("metadata.genre", "sci-fi"), + Query.startsWith("metadata.title", "Inter") +]) +``` +```server-python +Query.and_queries([ + Query.equal("metadata.genre", "sci-fi"), + Query.starts_with("metadata.title", "Inter") +]) +``` +```server-ruby +Query.and([ + Query.equal("metadata.genre", "sci-fi"), + Query.starts_with("metadata.title", "Inter") +]) +``` +```server-deno +Query.and([ + Query.equal("metadata.genre", "sci-fi"), + Query.startsWith("metadata.title", "Inter") +]) +``` +```server-php +Query::and([ + Query::equal("metadata.genre", "sci-fi"), + Query::startsWith("metadata.title", "Inter") +]) +``` +```client-apple +Query.and([ + Query.equal("metadata.genre", value: "sci-fi"), + Query.startsWith("metadata.title", value: "Inter") +]) +``` +```server-go +query.And([]string{ + query.Equal("metadata.genre", []string{"sci-fi"}), + query.StartsWith("metadata.title", "Inter"), +}) +``` +```server-nodejs +Query.and([ + Query.equal("metadata.genre", "sci-fi"), + Query.startsWith("metadata.title", "Inter") +]) +``` +```server-rust +Query::and(vec![ + Query::equal("metadata.genre", Value::String("sci-fi".to_string())).to_string(), + Query::starts_with("metadata.title", "Inter").to_string(), +]).to_string() +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"and","values":[{"method":"equal","attribute":"metadata.genre","values":["sci-fi"]},{"method":"startsWith","attribute":"metadata.title","values":["Inter"]}]}' +``` +```http +{"method":"and","values":[{"method":"equal","attribute":"metadata.genre","values":["sci-fi"]},{"method":"startsWith","attribute":"metadata.title","values":["Inter"]}]} +``` +{% /multicode %} + +### OR {% #or %} + +Returns document if it matches any of the nested sub-queries in the array passed in. + +{% multicode %} +```client-web +Query.or([ + Query.equal("metadata.genre", "romance"), + Query.equal("metadata.genre", "sci-fi") +]) +``` +```client-flutter +Query.or([ + Query.equal("metadata.genre", "romance"), + Query.equal("metadata.genre", "sci-fi") +]) +``` +```server-python +Query.or_queries([ + Query.equal("metadata.genre", "romance"), + Query.equal("metadata.genre", "sci-fi") +]) +``` +```server-ruby +Query.or([ + Query.equal("metadata.genre", "romance"), + Query.equal("metadata.genre", "sci-fi") +]) +``` +```server-deno +Query.or([ + Query.equal("metadata.genre", "romance"), + Query.equal("metadata.genre", "sci-fi") +]) +``` +```server-php +Query::or([ + Query::equal("metadata.genre", "romance"), + Query::equal("metadata.genre", "sci-fi") +]) +``` +```client-apple +Query.or([ + Query.equal("metadata.genre", value: "romance"), + Query.equal("metadata.genre", value: "sci-fi") +]) +``` +```server-go +query.Or([]string{ + query.Equal("metadata.genre", []string{"romance"}), + query.Equal("metadata.genre", []string{"sci-fi"}), +}) +``` +```server-nodejs +Query.or([ + Query.equal("metadata.genre", "romance"), + Query.equal("metadata.genre", "sci-fi") +]) +``` +```server-rust +Query::or(vec![ + Query::equal("metadata.genre", Value::String("romance".to_string())).to_string(), + Query::equal("metadata.genre", Value::String("sci-fi".to_string())).to_string(), +]).to_string() +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"or","values":[{"method":"equal","attribute":"metadata.genre","values":["romance"]},{"method":"equal","attribute":"metadata.genre","values":["sci-fi"]}]}' +``` +```http +{"method":"or","values":[{"method":"equal","attribute":"metadata.genre","values":["romance"]},{"method":"equal","attribute":"metadata.genre","values":["sci-fi"]}]} +``` +{% /multicode %} + +## Ordering {% #ordering %} + +Order results by a top-level document attribute such as `$createdAt`, `$updatedAt`, or `$id`. Ordering by a nested `metadata` field is not supported. + +### Order descending {% #order-desc %} + +Orders results in descending order by attribute. + +{% multicode %} +```client-web +Query.orderDesc("$createdAt") +``` +```client-flutter +Query.orderDesc("$createdAt") +``` +```server-python +Query.order_desc("$createdAt") +``` +```server-ruby +Query.order_desc("$createdAt") +``` +```server-nodejs +Query.orderDesc("$createdAt") +``` +```server-php +Query::orderDesc("$createdAt") +``` +```client-apple +Query.orderDesc("$createdAt") +``` +```server-go +query.OrderDesc("$createdAt") +``` +```server-rust +Query::order_desc("$createdAt").to_string() +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"orderDesc","attribute":"$createdAt"}' +``` +```http +{"method":"orderDesc","attribute":"$createdAt"} +``` +{% /multicode %} + +### Order ascending {% #order-asc %} + +Orders results in ascending order by attribute. + +{% multicode %} +```client-web +Query.orderAsc("$createdAt") +``` +```client-flutter +Query.orderAsc("$createdAt") +``` +```server-python +Query.order_asc("$createdAt") +``` +```server-ruby +Query.order_asc("$createdAt") +``` +```server-nodejs +Query.orderAsc("$createdAt") +``` +```server-php +Query::orderAsc("$createdAt") +``` +```client-apple +Query.orderAsc("$createdAt") +``` +```server-go +query.OrderAsc("$createdAt") +``` +```server-rust +Query::order_asc("$createdAt").to_string() +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"orderAsc","attribute":"$createdAt"}' +``` +```http +{"method":"orderAsc","attribute":"$createdAt"} +``` +{% /multicode %} + +### Order random {% #order-random %} + +Orders results in random order. + +{% multicode %} +```client-web +Query.orderRandom() +``` +```client-flutter +Query.orderRandom() +``` +```server-python +Query.order_random() +``` +```server-ruby +Query.order_random() +``` +```server-nodejs +Query.orderRandom() +``` +```server-php +Query::orderRandom() +``` +```client-apple +Query.orderRandom() +``` +```server-go +query.OrderRandom() +``` +```server-rust +Query::order_random().to_string() +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"orderRandom"}' +``` +```http +{"method":"orderRandom"} +``` +{% /multicode %} + +## Pagination {% #pagination %} + +### Limit {% #limit %} + +Limits the number of results returned by the query. Used for [pagination](/docs/products/databases/vectorsdb/pagination). + +{% multicode %} +```client-web +Query.limit(25) +``` +```client-flutter +Query.limit(25) +``` +```server-python +Query.limit(25) +``` +```server-ruby +Query.limit(25) +``` +```server-deno +Query.limit(25) +``` +```server-php +Query::limit(25) +``` +```client-apple +Query.limit(25) +``` +```server-go +query.Limit(25) +``` +```server-nodejs +Query.limit(25) +``` +```server-rust +Query::limit(25).to_string() +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"limit","values":[25]}' +``` +```http +{"method":"limit","values":[25]} +``` +{% /multicode %} + +### Offset {% #offset %} + +Offset the results returned by skipping some of the results. Used for [pagination](/docs/products/databases/vectorsdb/pagination). + +{% multicode %} +```client-web +Query.offset(0) +``` +```client-flutter +Query.offset(0) +``` +```server-python +Query.offset(0) +``` +```server-ruby +Query.offset(0) +``` +```server-deno +Query.offset(0) +``` +```server-php +Query::offset(0) +``` +```client-apple +Query.offset(0) +``` +```server-go +query.Offset(0) +``` +```server-nodejs +Query.offset(0) +``` +```server-rust +Query::offset(0).to_string() +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"offset","values":[0]}' +``` +```http +{"method":"offset","values":[0]} +``` +{% /multicode %} + +### Cursor after {% #cursor-after %} + +Places the cursor after the specified document ID. Used for [pagination](/docs/products/databases/vectorsdb/pagination). + +{% multicode %} +```client-web +Query.cursorAfter("62a7...f620") +``` +```client-flutter +Query.cursorAfter("62a7...f620") +``` +```server-python +Query.cursor_after("62a7...f620") +``` +```server-ruby +Query.cursor_after("62a7...f620") +``` +```server-deno +Query.cursorAfter("62a7...f620") +``` +```server-php +Query::cursorAfter("62a7...f620") +``` +```client-apple +Query.cursorAfter("62a7...f620") +``` +```server-go +query.CursorAfter("62a7...f620") +``` +```server-nodejs +Query.cursorAfter("62a7...f620") +``` +```server-rust +Query::cursor_after("62a7...f620").to_string() +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"cursorAfter","values":["62a7...f620"]}' +``` +```http +{"method":"cursorAfter","values":["62a7...f620"]} +``` +{% /multicode %} + +### Cursor before {% #cursor-before %} + +Places the cursor before the specified document ID. Used for [pagination](/docs/products/databases/vectorsdb/pagination). + +{% multicode %} +```client-web +Query.cursorBefore("62a7...a600") +``` +```client-flutter +Query.cursorBefore("62a7...a600") +``` +```server-python +Query.cursor_before("62a7...a600") +``` +```server-ruby +Query.cursor_before("62a7...a600") +``` +```server-deno +Query.cursorBefore("62a7...a600") +``` +```server-php +Query::cursorBefore("62a7...a600") +``` +```client-apple +Query.cursorBefore("62a7...a600") +``` +```server-go +query.CursorBefore("62a7...a600") +``` +```server-nodejs +Query.cursorBefore("62a7...a600") +``` +```server-rust +Query::cursor_before("62a7...a600").to_string() +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"cursorBefore","values":["62a7...a600"]}' +``` +```http +{"method":"cursorBefore","values":["62a7...a600"]} +``` +{% /multicode %} + +# Complex queries {% #complex-queries %} + +You can create complex queries by combining AND and OR operations. For example, to find documents that are either sci-fi released after 2010 or romance released before 2005: + +{% multicode %} +```client-web +const results = await vectorsDB.listDocuments({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + Query.or([ + Query.and([ + Query.equal('metadata.genre', ['sci-fi']), + Query.greaterThan('metadata.year', '2010') + ]), + Query.and([ + Query.equal('metadata.genre', ['romance']), + Query.lessThan('metadata.year', '2005') + ]) + ]) + ] +}); +``` +```client-flutter +final results = await vectorsDB.listDocuments( + '<DATABASE_ID>', + '<COLLECTION_ID>', + [ + Query.or([ + Query.and([ + Query.equal('metadata.genre', ['sci-fi']), + Query.greaterThan('metadata.year', '2010') + ]), + Query.and([ + Query.equal('metadata.genre', ['romance']), + Query.lessThan('metadata.year', '2005') + ]) + ]) + ] +); +``` +```server-nodejs +const results = await vectorsDB.listDocuments({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + Query.or([ + Query.and([ + Query.equal('metadata.genre', ['sci-fi']), + Query.greaterThan('metadata.year', '2010') + ]), + Query.and([ + Query.equal('metadata.genre', ['romance']), + Query.lessThan('metadata.year', '2005') + ]) + ]) + ] +}); +``` +```server-python +results = vectorsDB.list_documents( + database_id='<DATABASE_ID>', + collection_id='<COLLECTION_ID>', + queries=[ + Query.or_queries([ + Query.and_queries([ + Query.equal('metadata.genre', ['sci-fi']), + Query.greater_than('metadata.year', '2010') + ]), + Query.and_queries([ + Query.equal('metadata.genre', ['romance']), + Query.less_than('metadata.year', '2005') + ]) + ]) + ] +) +``` +```server-go +documents, err := vectorsDB.ListDocuments( + "<DATABASE_ID>", + "<COLLECTION_ID>", + vectorsDB.WithListDocumentsQueries([]string{ + query.Or([]string{ + query.And([]string{ + query.Equal("metadata.genre", []string{"sci-fi"}), + query.GreaterThan("metadata.year", "2010"), + }), + query.And([]string{ + query.Equal("metadata.genre", []string{"romance"}), + query.LessThan("metadata.year", "2005"), + }), + }), + }), +) +if err != nil { + log.Fatal(err) +} +``` +```server-rust +let documents = vectors_db.list_documents( + "<DATABASE_ID>", + "<COLLECTION_ID>", + Some(vec![ + Query::or(vec![ + Query::and(vec![ + Query::equal("metadata.genre", Value::Array(vec![Value::String("sci-fi".to_string())])).to_string(), + Query::greater_than("metadata.year", "2010").to_string(), + ]).to_string(), + Query::and(vec![ + Query::equal("metadata.genre", Value::Array(vec![Value::String("romance".to_string())])).to_string(), + Query::less_than("metadata.year", "2005").to_string(), + ]).to_string(), + ]).to_string(), + ]), + None, + None, + None, +).await?; +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"or","values":[{"method":"and","values":[{"method":"equal","attribute":"metadata.genre","values":["sci-fi"]},{"method":"greaterThan","attribute":"metadata.year","values":["2010"]}]},{"method":"and","values":[{"method":"equal","attribute":"metadata.genre","values":["romance"]},{"method":"lessThan","attribute":"metadata.year","values":["2005"]}]}]}' +``` +```http +{"method":"or","values":[{"method":"and","values":[{"method":"equal","attribute":"metadata.genre","values":["sci-fi"]},{"method":"greaterThan","attribute":"metadata.year","values":["2010"]}]},{"method":"and","values":[{"method":"equal","attribute":"metadata.genre","values":["romance"]},{"method":"lessThan","attribute":"metadata.year","values":["2005"]}]}]} +``` +{% /multicode %} + +This example demonstrates how to combine `OR` and `AND` operations. The query uses `Query.or()` to match either condition: sci-fi released after 2010 OR romance released before 2005. +Each condition within the OR is composed of two AND conditions, one for the genre and one for the year. The database returns documents that match either of these combined conditions. + +{% arrow_link href="/docs/products/databases/vectorsdb/vector-search" %} +Learn about vector search +{% /arrow_link %} diff --git a/src/routes/docs/products/databases/vectorsdb/quick-start/+page.markdoc b/src/routes/docs/products/databases/vectorsdb/quick-start/+page.markdoc new file mode 100644 index 00000000000..3586d5bc965 --- /dev/null +++ b/src/routes/docs/products/databases/vectorsdb/quick-start/+page.markdoc @@ -0,0 +1,1034 @@ +--- +layout: article +title: Start with VectorsDB +description: Get started with Appwrite VectorsDB. Follow a step-by-step guide to create your first database, add a collection with a fixed dimension, store embeddings with metadata, and read them back. +--- + + +VectorsDB stores embedding vectors so you can build features like semantic search, recommendations, and retrieval for AI applications. +This guide walks through creating a database, adding a collection with a fixed `dimension`, storing a document with its `embeddings` and `metadata`, and reading it back. + +These steps use a [Server SDK](/docs/sdks#server), which requires an [API key](/docs/advanced/platform/api-keys). + +{% section #create-database step=1 title="Create database" %} +Head to your [Appwrite Console](https://cloud.appwrite.io/console/) and click **Create database**. Name it `Knowledge base` and choose **VectorsDB** as the database type. +Optionally, add a custom database ID. Select your preferred tier, then click **Create database**. + +You can also create a database programmatically with the `create` method. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.create({ + databaseId: sdk.ID.unique(), + name: 'Knowledge base' +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.create({ + databaseId: sdk.ID.unique(), + name: 'Knowledge base' +}); +``` +```php +<?php + +use Appwrite\Client; +use Appwrite\Services\VectorsDB; +use Appwrite\ID; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('<YOUR_PROJECT_ID>') // Your project ID + ->setKey('<YOUR_API_KEY>'); // Your secret API key + +$vectorsDB = new VectorsDB($client); + +$result = $vectorsDB->create( + databaseId: ID::unique(), + name: 'Knowledge base' +); +``` +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB +from appwrite.id import ID + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('<YOUR_PROJECT_ID>') # Your project ID +client.set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB(client) + +result = vectors_db.create( + database_id = ID.unique(), + name = 'Knowledge base' +) +``` +```ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('<YOUR_PROJECT_ID>') # Your project ID + .set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB.new(client) + +result = vectors_db.create( + database_id: ID.unique(), + name: 'Knowledge base' +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("<YOUR_PROJECT_ID>") // Your project ID + .SetKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +Database result = await vectorsDB.Create( + databaseId: ID.Unique(), + name: "Knowledge base" +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +VectorsDB vectorsDB = VectorsDB(client); + +Database result = await vectorsDB.create( + databaseId: ID.unique(), + name: 'Knowledge base', +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.ID +import io.appwrite.services.VectorsDB + +val client = Client(context) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +val vectorsDB = VectorsDB(client) + +val response = vectorsDB.create( + databaseId = ID.unique(), + name = "Knowledge base", +) +``` +```java +import io.appwrite.Client; +import io.appwrite.ID; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.VectorsDB; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +vectorsDB.create( + ID.unique(), + "Knowledge base", + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +let vectorsDB = VectorsDB(client) + +let database = try await vectorsDB.create( + databaseId: ID.unique(), + name: "Knowledge base" +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; +use appwrite::id::ID; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.create( + ID::unique(), + "Knowledge base", + None, // enabled (optional) + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite vectors-db create \ + --database-id <DATABASE_ID> \ + --name "Knowledge base" +``` +{% /multicode %} +{% /section %} + +{% section #create-collection step=2 title="Create collection" %} +In the `Knowledge base` database, click **Create collection** and name it `Articles`. Optionally, add a custom collection ID. + +A VectorsDB collection has a fixed `dimension`, the length of the embedding vectors it holds. All documents in the collection must use vectors of that exact length, so set the `dimension` to match the embedding model you plan to use. This guide uses `dimension: 4` to keep the vectors short and readable. The default `nomic-embed-text` [embedding model](/docs/products/databases/vectorsdb/embeddings) produces 768-dimensional vectors, so a production collection would use `dimension: 768`. + +The schema is provisioned for you: an `embeddings` vector and an optional `metadata` object. There are no columns to define. + +Set the **dimension**, then add a **Read** permission for the **Any** role so anyone can read documents. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.createCollection({ + databaseId: '<DATABASE_ID>', + collectionId: sdk.ID.unique(), + name: 'Articles', + dimension: 4, + permissions: [sdk.Permission.read(sdk.Role.any())] // optional +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.createCollection({ + databaseId: '<DATABASE_ID>', + collectionId: sdk.ID.unique(), + name: 'Articles', + dimension: 4, + permissions: [sdk.Permission.read(sdk.Role.any())] // optional +}); +``` +```php +<?php + +use Appwrite\Client; +use Appwrite\Services\VectorsDB; +use Appwrite\ID; +use Appwrite\Permission; +use Appwrite\Role; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('<YOUR_PROJECT_ID>') // Your project ID + ->setKey('<YOUR_API_KEY>'); // Your secret API key + +$vectorsDB = new VectorsDB($client); + +$result = $vectorsDB->createCollection( + databaseId: '<DATABASE_ID>', + collectionId: ID::unique(), + name: 'Articles', + dimension: 4, + permissions: [Permission::read(Role::any())] // optional +); +``` +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB +from appwrite.id import ID +from appwrite.permission import Permission +from appwrite.role import Role + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('<YOUR_PROJECT_ID>') # Your project ID +client.set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB(client) + +result = vectors_db.create_collection( + database_id = '<DATABASE_ID>', + collection_id = ID.unique(), + name = 'Articles', + dimension = 4, + permissions = [Permission.read(Role.any())] # optional +) +``` +```ruby +require 'appwrite' + +include Appwrite +include Appwrite::Permission +include Appwrite::Role + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('<YOUR_PROJECT_ID>') # Your project ID + .set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB.new(client) + +result = vectors_db.create_collection( + database_id: '<DATABASE_ID>', + collection_id: ID.unique(), + name: 'Articles', + dimension: 4, + permissions: [Permission.read(Role.any())] # optional +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("<YOUR_PROJECT_ID>") // Your project ID + .SetKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +Collection result = await vectorsDB.CreateCollection( + databaseId: "<DATABASE_ID>", + collectionId: ID.Unique(), + name: "Articles", + dimension: 4, + permissions: new List<string> { Permission.Read(Role.Any()) } // optional +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +VectorsDB vectorsDB = VectorsDB(client); + +Collection result = await vectorsDB.createCollection( + databaseId: '<DATABASE_ID>', + collectionId: ID.unique(), + name: 'Articles', + dimension: 4, + permissions: [Permission.read(Role.any())], // optional +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.ID +import io.appwrite.Permission +import io.appwrite.Role +import io.appwrite.services.VectorsDB + +val client = Client(context) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +val vectorsDB = VectorsDB(client) + +val response = vectorsDB.createCollection( + databaseId = "<DATABASE_ID>", + collectionId = ID.unique(), + name = "Articles", + dimension = 4, + permissions = listOf(Permission.read(Role.any())), // optional +) +``` +```java +import io.appwrite.Client; +import io.appwrite.ID; +import io.appwrite.Permission; +import io.appwrite.Role; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.VectorsDB; +import java.util.List; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +vectorsDB.createCollection( + "<DATABASE_ID>", + ID.unique(), + "Articles", + 4, + List.of(Permission.read(Role.any())), + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +let vectorsDB = VectorsDB(client) + +let collection = try await vectorsDB.createCollection( + databaseId: "<DATABASE_ID>", + collectionId: ID.unique(), + name: "Articles", + dimension: 4, + permissions: [Permission.read(Role.any())] // optional +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; +use appwrite::id::ID; +use appwrite::permission::Permission; +use appwrite::role::Role; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.create_collection( + "<DATABASE_ID>", + ID::unique(), + "Articles", + 4, + Some(vec![Permission::read(Role::any()).to_string()]), // permissions (optional) + None, // documentSecurity (optional) + None, // enabled (optional) + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite vectors-db create-collection \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --name "Articles" \ + --dimension 4 \ + --permissions 'read("any")' +``` +{% /multicode %} +{% /section %} + +{% section #store-documents step=3 title="Store documents" %} +A document's data is an `embeddings` vector and an optional `metadata` object. +The `embeddings` array length must equal the collection's `dimension`, and `metadata` is free-form JSON you can use to store any data you want to keep alongside the vector. + +The vectors here are hardcoded so the example runs on its own. In an application, you generate them from your text with [embeddings](/docs/products/databases/vectorsdb/embeddings). + +Use the `createDocument` method to store the embedding and its metadata. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.createDocument({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: sdk.ID.unique(), + data: { + embeddings: [0.12, 0.84, 0.33, 0.57], + metadata: { title: 'Getting started with Appwrite', tags: ['guide'] } + } +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.createDocument({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: sdk.ID.unique(), + data: { + embeddings: [0.12, 0.84, 0.33, 0.57], + metadata: { title: 'Getting started with Appwrite', tags: ['guide'] } + } +}); +``` +```php +<?php + +use Appwrite\Client; +use Appwrite\Services\VectorsDB; +use Appwrite\ID; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('<YOUR_PROJECT_ID>') // Your project ID + ->setKey('<YOUR_API_KEY>'); // Your secret API key + +$vectorsDB = new VectorsDB($client); + +$result = $vectorsDB->createDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: ID::unique(), + data: [ + 'embeddings' => [0.12, 0.84, 0.33, 0.57], + 'metadata' => ['title' => 'Getting started with Appwrite', 'tags' => ['guide']] + ] +); +``` +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB +from appwrite.id import ID + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('<YOUR_PROJECT_ID>') # Your project ID +client.set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB(client) + +result = vectors_db.create_document( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>', + document_id = ID.unique(), + data = { + "embeddings": [0.12, 0.84, 0.33, 0.57], + "metadata": { "title": "Getting started with Appwrite", "tags": ["guide"] } + } +) +``` +```ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('<YOUR_PROJECT_ID>') # Your project ID + .set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB.new(client) + +result = vectors_db.create_document( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + document_id: ID.unique(), + data: { + "embeddings" => [0.12, 0.84, 0.33, 0.57], + "metadata" => { "title" => "Getting started with Appwrite", "tags" => ["guide"] } + } +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("<YOUR_PROJECT_ID>") // Your project ID + .SetKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +Document result = await vectorsDB.CreateDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: ID.Unique(), + data: new Dictionary<string, object> { + { "embeddings", new List<double> { 0.12, 0.84, 0.33, 0.57 } }, + { "metadata", new Dictionary<string, object> { { "title", "Getting started with Appwrite" }, { "tags", new List<string> { "guide" } } } } + } +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +VectorsDB vectorsDB = VectorsDB(client); + +Document result = await vectorsDB.createDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: ID.unique(), + data: { + "embeddings": [0.12, 0.84, 0.33, 0.57], + "metadata": { "title": "Getting started with Appwrite", "tags": ["guide"] } + }, +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.ID +import io.appwrite.services.VectorsDB + +val client = Client(context) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +val vectorsDB = VectorsDB(client) + +val response = vectorsDB.createDocument( + databaseId = "<DATABASE_ID>", + collectionId = "<COLLECTION_ID>", + documentId = ID.unique(), + data = mapOf( + "embeddings" to listOf(0.12, 0.84, 0.33, 0.57), + "metadata" to mapOf("title" to "Getting started with Appwrite", "tags" to listOf("guide")) + ), +) +``` +```java +import io.appwrite.Client; +import io.appwrite.ID; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.VectorsDB; +import java.util.List; +import java.util.Map; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +vectorsDB.createDocument( + "<DATABASE_ID>", + "<COLLECTION_ID>", + ID.unique(), + Map.of( + "embeddings", List.of(0.12, 0.84, 0.33, 0.57), + "metadata", Map.of("title", "Getting started with Appwrite", "tags", List.of("guide")) + ), + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +let vectorsDB = VectorsDB(client) + +let document = try await vectorsDB.createDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: ID.unique(), + data: [ + "embeddings": [0.12, 0.84, 0.33, 0.57], + "metadata": ["title": "Getting started with Appwrite", "tags": ["guide"]] + ] +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; +use appwrite::id::ID; +use serde_json::json; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.create_document( + "<DATABASE_ID>", + "<COLLECTION_ID>", + ID::unique(), + json!({ + "embeddings": [0.12, 0.84, 0.33, 0.57], + "metadata": { "title": "Getting started with Appwrite", "tags": ["guide"] } + }), + None, // permissions (optional) + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite vectors-db create-document \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --document-id 'unique()' \ + --data '{ "embeddings": [0.12, 0.84, 0.33, 0.57], "metadata": { "title": "Getting started with Appwrite", "tags": ["guide"] } }' +``` +{% /multicode %} + +The response includes the stored `embeddings` and `metadata` alongside the document's system fields. + +```json +{ + "embeddings": [0.12, 0.84, 0.33, 0.57], + "metadata": { "title": "Getting started with Appwrite", "tags": ["guide"] }, + "$id": "6a43c07100195469a012", + "$sequence": "1", + "$createdAt": "2026-06-30T13:11:13.441+00:00", + "$updatedAt": "2026-06-30T13:11:13.441+00:00", + "$permissions": [], + "$databaseId": "650125c64b3c25ce4bc4", + "$collectionId": "650125cff227cf9f95ad" +} +``` +{% /section %} + +{% section #read-documents step=4 title="Read documents" %} +To read documents back from your collection, use the `listDocuments` method. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.listDocuments({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + sdk.Query.limit(10) + ] +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.listDocuments({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + sdk.Query.limit(10) + ] +}); +``` +```php +<?php + +use Appwrite\Client; +use Appwrite\Services\VectorsDB; +use Appwrite\Query; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('<YOUR_PROJECT_ID>') // Your project ID + ->setKey('<YOUR_API_KEY>'); // Your secret API key + +$vectorsDB = new VectorsDB($client); + +$result = $vectorsDB->listDocuments( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + Query::limit(10) + ] +); +``` +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB +from appwrite.query import Query + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('<YOUR_PROJECT_ID>') # Your project ID +client.set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB(client) + +result = vectors_db.list_documents( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>', + queries = [ + Query.limit(10) + ] +) +``` +```ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('<YOUR_PROJECT_ID>') # Your project ID + .set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB.new(client) + +result = vectors_db.list_documents( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + queries: [ + Query.limit(10) + ] +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; +using Appwrite.Queries; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("<YOUR_PROJECT_ID>") // Your project ID + .SetKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +DocumentList result = await vectorsDB.ListDocuments( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + queries: new List<string> { + Query.Limit(10) + } +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +VectorsDB vectorsDB = VectorsDB(client); + +DocumentList result = await vectorsDB.listDocuments( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + Query.limit(10) + ], +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.Query +import io.appwrite.services.VectorsDB + +val client = Client(context) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +val vectorsDB = VectorsDB(client) + +val response = vectorsDB.listDocuments( + databaseId = "<DATABASE_ID>", + collectionId = "<COLLECTION_ID>", + queries = listOf( + Query.limit(10) + ), +) +``` +```java +import io.appwrite.Client; +import io.appwrite.Query; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.VectorsDB; +import java.util.List; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +vectorsDB.listDocuments( + "<DATABASE_ID>", + "<COLLECTION_ID>", + List.of( + Query.limit(10) + ), + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +let vectorsDB = VectorsDB(client) + +let documents = try await vectorsDB.listDocuments( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + queries: [ + Query.limit(10) + ] +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; +use appwrite::query::Query; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.list_documents( + "<DATABASE_ID>", + "<COLLECTION_ID>", + Some(vec![Query::limit(10).to_string()]), + None, // transactionId (optional) + None, // total (optional) + None, // ttl (optional) + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"limit","values":[10]}' +``` +{% /multicode %} +{% /section %} + +{% section #next-steps step=5 title="Next steps" %} +You now have a database, a collection, and a document holding an embedding with its metadata. From here: + +- Generate vectors from your text instead of hardcoding them with [embeddings](/docs/products/databases/vectorsdb/embeddings). +- Find the documents closest to a query vector with [vector search](/docs/products/databases/vectorsdb/vector-search). + +{% arrow_link href="/docs/products/databases/vectorsdb/vector-search" %} +Run vector search +{% /arrow_link %} +{% /section %} diff --git a/src/routes/docs/products/databases/vectorsdb/timestamp-overrides/+page.markdoc b/src/routes/docs/products/databases/vectorsdb/timestamp-overrides/+page.markdoc new file mode 100644 index 00000000000..2956294d759 --- /dev/null +++ b/src/routes/docs/products/databases/vectorsdb/timestamp-overrides/+page.markdoc @@ -0,0 +1,1302 @@ +--- +layout: article +title: Timestamp overrides +description: Set custom $createdAt and $updatedAt timestamps for your documents when using server SDKs. +--- + +When creating or updating documents, Appwrite automatically sets `$createdAt` and `$updatedAt` timestamps. However, there are scenarios where you might need to set these timestamps manually, such as when migrating data from another system or backfilling historical records. + +{% info title="Server SDKs required" %} +To manually set `$createdAt` and `$updatedAt`, you must use a **server SDK** with an **API key**. These attributes can be passed inside the `data` parameter on any of the create, update, or upsert routes (single or bulk). +{% /info %} + +# Setting custom timestamps {% #setting-custom-timestamps %} + +You can override a document's timestamps by providing ISO 8601 strings (for example, `2025-08-10T12:34:56.000Z`) in the `data` payload. If these attributes are not provided, Appwrite will set them automatically. + +Custom timestamps work with all document operations: create, update, upsert, and their bulk variants. + +## Single document operations {% #single-document-operations %} + +When working with individual documents, you can set custom timestamps during create, update, and upsert operations. + +### Create with custom timestamps {% #create-custom %} + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<API_KEY>'); + +const vectorsDB = new sdk.VectorsDB(client); + +await vectorsDB.createDocument({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: sdk.ID.unique(), + data: { + '$createdAt': new Date('2025-08-10T12:34:56.000Z').toISOString(), + '$updatedAt': new Date('2025-08-10T12:34:56.000Z').toISOString(), + embeddings: [0.12, 0.84, 0.33, 0.57], + metadata: { title: 'Hamlet' } + } +}); +``` +```server-php +use Appwrite\Client; +use Appwrite\ID; +use Appwrite\Services\VectorsDB; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<YOUR_PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$vectorsDB = new VectorsDB($client); + +$vectorsDB->createDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: ID::unique(), + data: [ + '$createdAt' => (new DateTime('<CUSTOM_DATE>'))->format(DATE_ATOM), + '$updatedAt' => (new DateTime('<CUSTOM_DATE>'))->format(DATE_ATOM), + 'embeddings' => [0.12, 0.84, 0.33, 0.57], + 'metadata' => ['title' => 'Hamlet'] + ] +); +``` +```server-swift +import Appwrite +import Foundation + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<YOUR_PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let vectorsDB = VectorsDB(client) + +let isoFormatter = ISO8601DateFormatter() +isoFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds] +let customDate = isoFormatter.date(from: "<CUSTOM_DATE>") ?? Date() +let createdAt = isoFormatter.string(from: customDate) +let updatedAt = isoFormatter.string(from: customDate) + +do { + let created = try await vectorsDB.createDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: "<DOCUMENT_ID>", + data: [ + "$createdAt": createdAt, + "$updatedAt": updatedAt, + "embeddings": [0.12, 0.84, 0.33, 0.57], + "metadata": ["title": "Hamlet"] + ] + ) + print("Created:", created) +} catch { + print("Create error:", error) +} +``` +```server-python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB +from appwrite.id import ID +from datetime import datetime, timezone + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<API_KEY>') + +vectors_db = VectorsDB(client) + +iso = datetime(2025, 8, 10, 12, 34, 56, tzinfo=timezone.utc).isoformat() + +vectors_db.create_document( + database_id='<DATABASE_ID>', + collection_id='<COLLECTION_ID>', + document_id=ID.unique(), + data={ + '$createdAt': iso, + '$updatedAt': iso, + 'embeddings': [0.12, 0.84, 0.33, 0.57], + 'metadata': { 'title': 'Hamlet' } + } +) +``` +```server-ruby +require 'appwrite' +require 'time' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<YOUR_PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +vectors_db = VectorsDB.new(client) + +custom_date = Time.parse('2025-08-10T12:34:56.000Z').iso8601 + +vectors_db.create_document( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + document_id: ID.unique(), + data: { + '$createdAt' => custom_date, + '$updatedAt' => custom_date, + 'embeddings' => [0.12, 0.84, 0.33, 0.57], + 'metadata' => { 'title' => 'Hamlet' } + } +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<YOUR_PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +VectorsDB vectorsDB = new VectorsDB(client); + +string customDate = DateTimeOffset.Parse("2025-08-10T12:34:56.000Z").ToString("O"); + +await vectorsDB.CreateDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: ID.Unique(), + data: new Dictionary<string, object> + { + ["$createdAt"] = customDate, + ["$updatedAt"] = customDate, + ["embeddings"] = new List<double> { 0.12, 0.84, 0.33, 0.57 }, + ["metadata"] = new Dictionary<string, object> { ["title"] = "Hamlet" } + } +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<YOUR_PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +VectorsDB vectorsDB = VectorsDB(client); + +String customDate = DateTime.parse('2025-08-10T12:34:56.000Z').toIso8601String(); + +await vectorsDB.createDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: ID.unique(), + data: { + '\$createdAt': customDate, + '\$updatedAt': customDate, + 'embeddings': [0.12, 0.84, 0.33, 0.57], + 'metadata': { 'title': 'Hamlet' } + }, +); +``` +```rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; +use appwrite::id::ID; +use serde_json::json; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); + client.set_project("<PROJECT_ID>"); + client.set_key("<API_KEY>"); + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.create_document( + "<DATABASE_ID>", + "<COLLECTION_ID>", + ID::unique(), + json!({ + "$createdAt": "2025-08-10T12:34:56.000Z", + "$updatedAt": "2025-08-10T12:34:56.000Z", + "embeddings": [0.12, 0.84, 0.33, 0.57], + "metadata": { "title": "Hamlet" } + }), + None, // permissions (optional) + ).await?; + + println!("Created: {:?}", result); + Ok(()) +} +``` +{% /multicode %} + +### Update with custom timestamps {% #update-custom %} + +When updating documents, you can also set a custom `$updatedAt` timestamp. The existing `$createdAt` is preserved unless you provide a new one: + +{% multicode %} +```server-nodejs +await vectorsDB.updateDocument({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + data: { + '$updatedAt': new Date('2025-08-10T12:34:56.000Z').toISOString(), + metadata: { title: 'Hamlet, revised' } + } +}); +``` +```server-php +$vectorsDB->updateDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + data: [ + '$updatedAt' => (new DateTime('<CUSTOM_DATE>'))->format(DATE_ATOM), + 'metadata' => ['title' => 'Hamlet, revised'] + ] +); +``` +```server-python +from datetime import datetime, timezone + +vectors_db.update_document( + database_id='<DATABASE_ID>', + collection_id='<COLLECTION_ID>', + document_id='<DOCUMENT_ID>', + data={ + '$updatedAt': datetime(2025, 8, 10, 12, 34, 56, tzinfo=timezone.utc).isoformat(), + 'metadata': { 'title': 'Hamlet, revised' } + } +) +``` +```server-swift +import Appwrite +import Foundation + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<YOUR_PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let vectorsDB = VectorsDB(client) + +let isoFormatter = ISO8601DateFormatter() +isoFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds] +let updatedAt = isoFormatter.string(from: isoFormatter.date(from: "<CUSTOM_DATE>") ?? Date()) + +do { + let updated = try await vectorsDB.updateDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: "<DOCUMENT_ID>", + data: [ + "$updatedAt": updatedAt, + "metadata": ["title": "Hamlet, revised"] + ] + ) + print("Updated:", updated) +} catch { + print("Update error:", error) +} +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<YOUR_PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +vectors_db = VectorsDB.new(client) + +custom_date = Time.parse('<CUSTOM_DATE>').iso8601 + +vectors_db.update_document( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + document_id: '<DOCUMENT_ID>', + data: { + '$updatedAt' => custom_date, + 'metadata' => { 'title' => 'Hamlet, revised' } + } +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<YOUR_PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +VectorsDB vectorsDB = new VectorsDB(client); + +string customDate = DateTimeOffset.Parse("<CUSTOM_DATE>").ToString("O"); + +await vectorsDB.UpdateDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: "<DOCUMENT_ID>", + data: new Dictionary<string, object> + { + ["$updatedAt"] = customDate, + ["metadata"] = new Dictionary<string, object> { ["title"] = "Hamlet, revised" } + } +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<YOUR_PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +VectorsDB vectorsDB = VectorsDB(client); + +String customDate = DateTime.parse('<CUSTOM_DATE>').toIso8601String(); + +await vectorsDB.updateDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + data: { + '\$updatedAt': customDate, + 'metadata': { 'title': 'Hamlet, revised' } + }, +); +``` +```rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; +use serde_json::json; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); + client.set_project("<PROJECT_ID>"); + client.set_key("<API_KEY>"); + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.update_document( + "<DATABASE_ID>", + "<COLLECTION_ID>", + "<DOCUMENT_ID>", + Some(json!({ + "$updatedAt": "2025-08-10T12:34:56.000Z", + "metadata": { "title": "Hamlet, revised" } + })), + None, // permissions (optional) + None, // transactionId (optional) + ).await?; + + println!("Updated: {:?}", result); + Ok(()) +} +``` +{% /multicode %} + +## Bulk operations {% #bulk-operations %} + +Custom timestamps also work with bulk operations, allowing you to set different timestamps for each document in the batch: + +### Bulk create {% #bulk-create %} + +{% multicode %} +```server-nodejs +await vectorsDB.createDocuments({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documents: [ + { + '$id': sdk.ID.unique(), + '$createdAt': new Date('2024-01-01T00:00:00.000Z').toISOString(), + '$updatedAt': new Date('2024-01-01T00:00:00.000Z').toISOString(), + embeddings: [0.1, 0.1, 0.1, 0.1], + metadata: { batch: 1 } + }, + { + '$id': sdk.ID.unique(), + '$createdAt': new Date('2024-02-01T00:00:00.000Z').toISOString(), + '$updatedAt': new Date('2024-02-01T00:00:00.000Z').toISOString(), + embeddings: [0.2, 0.2, 0.2, 0.2], + metadata: { batch: 2 } + } + ] +}); +``` +```server-python +vectors_db.create_documents( + database_id='<DATABASE_ID>', + collection_id='<COLLECTION_ID>', + documents=[ + { + '$id': ID.unique(), + '$createdAt': datetime(2024, 1, 1, tzinfo=timezone.utc).isoformat(), + '$updatedAt': datetime(2024, 1, 1, tzinfo=timezone.utc).isoformat(), + 'embeddings': [0.1, 0.1, 0.1, 0.1], + 'metadata': { 'batch': 1 } + }, + { + '$id': ID.unique(), + '$createdAt': datetime(2024, 2, 1, tzinfo=timezone.utc).isoformat(), + '$updatedAt': datetime(2024, 2, 1, tzinfo=timezone.utc).isoformat(), + 'embeddings': [0.2, 0.2, 0.2, 0.2], + 'metadata': { 'batch': 2 } + } + ] +) +``` +```server-php +use Appwrite\Client; +use Appwrite\ID; +use Appwrite\Services\VectorsDB; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<YOUR_PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$vectorsDB = new VectorsDB($client); + +$vectorsDB->createDocuments( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documents: [ + [ + '$id' => ID::unique(), + '$createdAt' => (new DateTime('<CUSTOM_DATE>'))->format(DATE_ATOM), + '$updatedAt' => (new DateTime('<CUSTOM_DATE>'))->format(DATE_ATOM), + 'embeddings' => [0.1, 0.1, 0.1, 0.1], + 'metadata' => ['batch' => 1] + ], + [ + '$id' => ID::unique(), + '$createdAt' => (new DateTime('<CUSTOM_DATE>'))->format(DATE_ATOM), + '$updatedAt' => (new DateTime('<CUSTOM_DATE>'))->format(DATE_ATOM), + 'embeddings' => [0.2, 0.2, 0.2, 0.2], + 'metadata' => ['batch' => 2] + ], + ] +); +``` +```server-swift +import Appwrite +import Foundation + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<YOUR_PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let vectorsDB = VectorsDB(client) + +let isoFormatter = ISO8601DateFormatter() +isoFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds] + +let first = isoFormatter.string(from: isoFormatter.date(from: "<CUSTOM_DATE>") ?? Date()) +let second = isoFormatter.string(from: isoFormatter.date(from: "<CUSTOM_DATE>") ?? Date()) + +do { + let bulkCreated = try await vectorsDB.createDocuments( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documents: [ + [ + "$id": ID.unique(), + "$createdAt": first, + "$updatedAt": first, + "embeddings": [0.1, 0.1, 0.1, 0.1], + "metadata": ["batch": 1] + ], + [ + "$id": ID.unique(), + "$createdAt": second, + "$updatedAt": second, + "embeddings": [0.2, 0.2, 0.2, 0.2], + "metadata": ["batch": 2] + ] + ] + ) + print("Bulk create:", bulkCreated) +} catch { + print("Bulk create error:", error) +} +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<YOUR_PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +vectors_db = VectorsDB.new(client) + +first = Time.parse('<CUSTOM_DATE>').iso8601 +second = Time.parse('<CUSTOM_DATE>').iso8601 + +vectors_db.create_documents( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + documents: [ + { + '$id' => ID.unique(), + '$createdAt' => first, + '$updatedAt' => first, + 'embeddings' => [0.1, 0.1, 0.1, 0.1], + 'metadata' => { 'batch' => 1 } + }, + { + '$id' => ID.unique(), + '$createdAt' => second, + '$updatedAt' => second, + 'embeddings' => [0.2, 0.2, 0.2, 0.2], + 'metadata' => { 'batch' => 2 } + } + ] +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<YOUR_PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +VectorsDB vectorsDB = new VectorsDB(client); + +string first = DateTimeOffset.Parse("<CUSTOM_DATE>").ToString("O"); +string second = DateTimeOffset.Parse("<CUSTOM_DATE>").ToString("O"); + +await vectorsDB.CreateDocuments( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documents: new List<object> + { + new Dictionary<string, object> + { + ["$id"] = ID.Unique(), + ["$createdAt"] = first, + ["$updatedAt"] = first, + ["embeddings"] = new List<double> { 0.1, 0.1, 0.1, 0.1 }, + ["metadata"] = new Dictionary<string, object> { ["batch"] = 1 } + }, + new Dictionary<string, object> + { + ["$id"] = ID.Unique(), + ["$createdAt"] = second, + ["$updatedAt"] = second, + ["embeddings"] = new List<double> { 0.2, 0.2, 0.2, 0.2 }, + ["metadata"] = new Dictionary<string, object> { ["batch"] = 2 } + } + } +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<YOUR_PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +VectorsDB vectorsDB = VectorsDB(client); + +String first = DateTime.parse('<CUSTOM_DATE>').toIso8601String(); +String second = DateTime.parse('<CUSTOM_DATE>').toIso8601String(); + +await vectorsDB.createDocuments( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documents: [ + { + '\$id': ID.unique(), + '\$createdAt': first, + '\$updatedAt': first, + 'embeddings': [0.1, 0.1, 0.1, 0.1], + 'metadata': { 'batch': 1 } + }, + { + '\$id': ID.unique(), + '\$createdAt': second, + '\$updatedAt': second, + 'embeddings': [0.2, 0.2, 0.2, 0.2], + 'metadata': { 'batch': 2 } + } + ], +); +``` +```rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; +use appwrite::id::ID; +use serde_json::json; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); + client.set_project("<PROJECT_ID>"); + client.set_key("<API_KEY>"); + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.create_documents( + "<DATABASE_ID>", + "<COLLECTION_ID>", + vec![ + json!({ + "$id": ID::unique(), + "$createdAt": "2024-01-01T00:00:00.000Z", + "$updatedAt": "2024-01-01T00:00:00.000Z", + "embeddings": [0.1, 0.1, 0.1, 0.1], + "metadata": { "batch": 1 } + }), + json!({ + "$id": ID::unique(), + "$createdAt": "2024-02-01T00:00:00.000Z", + "$updatedAt": "2024-02-01T00:00:00.000Z", + "embeddings": [0.2, 0.2, 0.2, 0.2], + "metadata": { "batch": 2 } + }), + ], + ).await?; + + println!("Bulk create: {:?}", result); + Ok(()) +} +``` +{% /multicode %} + +### Bulk upsert {% #bulk-upsert %} + +{% multicode %} +```server-nodejs +await vectorsDB.upsertDocuments({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documents: [ + { + '$id': '<DOCUMENT_ID_OR_NEW_ID>', + '$createdAt': new Date('2024-01-01T00:00:00.000Z').toISOString(), + '$updatedAt': new Date('2025-01-01T00:00:00.000Z').toISOString(), + embeddings: [0.3, 0.3, 0.3, 0.3], + metadata: { source: 'sync' } + } + ] +}); +``` +```server-python +vectors_db.upsert_documents( + database_id='<DATABASE_ID>', + collection_id='<COLLECTION_ID>', + documents=[ + { + '$id': '<DOCUMENT_ID_OR_NEW_ID>', + '$createdAt': datetime(2024, 1, 1, tzinfo=timezone.utc).isoformat(), + '$updatedAt': datetime(2025, 1, 1, tzinfo=timezone.utc).isoformat(), + 'embeddings': [0.3, 0.3, 0.3, 0.3], + 'metadata': { 'source': 'sync' } + } + ] +) +``` +```server-php +use Appwrite\Client; +use Appwrite\ID; +use Appwrite\Services\VectorsDB; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<YOUR_PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$vectorsDB = new VectorsDB($client); + +$vectorsDB->upsertDocuments( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documents: [ + [ + '$id' => '<DOCUMENT_ID_OR_NEW_ID>', + '$createdAt' => (new DateTime('<CUSTOM_DATE>'))->format(DATE_ATOM), + '$updatedAt' => (new DateTime('<CUSTOM_DATE>'))->format(DATE_ATOM), + 'embeddings' => [0.3, 0.3, 0.3, 0.3], + 'metadata' => ['source' => 'sync'] + ], + ] +); +``` +```server-swift +import Appwrite +import Foundation + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<YOUR_PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let vectorsDB = VectorsDB(client) + +let isoFormatter = ISO8601DateFormatter() +isoFormatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds] +let createdAt = isoFormatter.string(from: isoFormatter.date(from: "<CUSTOM_DATE>") ?? Date()) +let updatedAt = isoFormatter.string(from: isoFormatter.date(from: "<CUSTOM_DATE>") ?? Date()) + +do { + let bulkUpserted = try await vectorsDB.upsertDocuments( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documents: [ + [ + "$id": "<DOCUMENT_ID_OR_NEW_ID>", + "$createdAt": createdAt, + "$updatedAt": updatedAt, + "embeddings": [0.3, 0.3, 0.3, 0.3], + "metadata": ["source": "sync"] + ] + ] + ) + print("Bulk upsert:", bulkUpserted) +} catch { + print("Bulk upsert error:", error) +} +``` +```server-ruby +require 'appwrite' +require 'time' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<YOUR_PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +vectors_db = VectorsDB.new(client) + +custom_date = Time.parse('<CUSTOM_DATE>').iso8601 + +vectors_db.upsert_documents( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + documents: [ + { + '$id' => '<DOCUMENT_ID_OR_NEW_ID>', + '$createdAt' => custom_date, + '$updatedAt' => custom_date, + 'embeddings' => [0.3, 0.3, 0.3, 0.3], + 'metadata' => { 'source' => 'sync' } + } + ] +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<YOUR_PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +VectorsDB vectorsDB = new VectorsDB(client); + +string createdAt = DateTimeOffset.Parse("<CUSTOM_DATE>").ToString("O"); +string updatedAt = DateTimeOffset.Parse("<CUSTOM_DATE>").ToString("O"); + +await vectorsDB.UpsertDocuments( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documents: new List<object> + { + new Dictionary<string, object> + { + ["$id"] = "<DOCUMENT_ID_OR_NEW_ID>", + ["$createdAt"] = createdAt, + ["$updatedAt"] = updatedAt, + ["embeddings"] = new List<double> { 0.3, 0.3, 0.3, 0.3 }, + ["metadata"] = new Dictionary<string, object> { ["source"] = "sync" } + } + } +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<YOUR_PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +VectorsDB vectorsDB = VectorsDB(client); + +String createdAt = DateTime.parse('<CUSTOM_DATE>').toIso8601String(); +String updatedAt = DateTime.parse('<CUSTOM_DATE>').toIso8601String(); + +await vectorsDB.upsertDocuments( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documents: [ + { + '\$id': '<DOCUMENT_ID_OR_NEW_ID>', + '\$createdAt': createdAt, + '\$updatedAt': updatedAt, + 'embeddings': [0.3, 0.3, 0.3, 0.3], + 'metadata': { 'source': 'sync' } + } + ], +); +``` +```rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; +use serde_json::json; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); + client.set_project("<PROJECT_ID>"); + client.set_key("<API_KEY>"); + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.upsert_documents( + "<DATABASE_ID>", + "<COLLECTION_ID>", + vec![ + json!({ + "$id": "<DOCUMENT_ID_OR_NEW_ID>", + "$createdAt": "2024-01-01T00:00:00.000Z", + "$updatedAt": "2025-01-01T00:00:00.000Z", + "embeddings": [0.3, 0.3, 0.3, 0.3], + "metadata": { "source": "sync" } + }), + ], + None, // transactionId (optional) + ).await?; + + println!("Bulk upsert: {:?}", result); + Ok(()) +} +``` +{% /multicode %} + +# Common use cases {% #use-cases %} + +Custom timestamps are particularly useful in several scenarios: + +## Data migration {% #data-migration %} +When migrating existing vectors from another system, you can preserve the original +creation and modification times: + +{% multicode %} +```server-nodejs +await vectorsDB.createDocument({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: sdk.ID.unique(), + data: { + '$createdAt': '<ORIGINAL_CREATED_AT_ISO>', + '$updatedAt': '<LAST_MODIFIED_ISO>', + embeddings: [0.12, 0.84, 0.33, 0.57], + metadata: { title: 'Imported post' } + } +}); +``` +```server-php +$vectorsDB->createDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: ID::unique(), + data: [ + '$createdAt' => '<ORIGINAL_CREATED_AT_ISO>', + '$updatedAt' => '<LAST_MODIFIED_ISO>', + 'embeddings' => [0.12, 0.84, 0.33, 0.57], + 'metadata' => ['title' => 'Imported post'] + ] +); +``` +```server-swift +let _ = try await vectorsDB.createDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: ID.unique(), + data: [ + "$createdAt": "<ORIGINAL_CREATED_AT_ISO>", + "$updatedAt": "<LAST_MODIFIED_ISO>", + "embeddings": [0.12, 0.84, 0.33, 0.57], + "metadata": ["title": "Imported post"] + ] +) +``` +```server-python +vectors_db.create_document( + database_id='<DATABASE_ID>', + collection_id='<COLLECTION_ID>', + document_id=ID.unique(), + data={ + '$createdAt': '<ORIGINAL_CREATED_AT_ISO>', + '$updatedAt': '<LAST_MODIFIED_ISO>', + 'embeddings': [0.12, 0.84, 0.33, 0.57], + 'metadata': { 'title': 'Imported post' } + } +) +``` +```server-ruby +vectors_db.create_document( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + document_id: ID.unique(), + data: { + '$createdAt' => '<ORIGINAL_CREATED_AT_ISO>', + '$updatedAt' => '<LAST_MODIFIED_ISO>', + 'embeddings' => [0.12, 0.84, 0.33, 0.57], + 'metadata' => { 'title' => 'Imported post' } + } +) +``` +```server-dotnet +await vectorsDB.CreateDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: ID.Unique(), + data: new Dictionary<string, object> + { + ["$createdAt"] = "<ORIGINAL_CREATED_AT_ISO>", + ["$updatedAt"] = "<LAST_MODIFIED_ISO>", + ["embeddings"] = new List<double> { 0.12, 0.84, 0.33, 0.57 }, + ["metadata"] = new Dictionary<string, object> { ["title"] = "Imported post" } + } +); +``` +```server-dart +await vectorsDB.createDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: ID.unique(), + data: { + '\$createdAt': '<ORIGINAL_CREATED_AT_ISO>', + '\$updatedAt': '<LAST_MODIFIED_ISO>', + 'embeddings': [0.12, 0.84, 0.33, 0.57], + 'metadata': { 'title': 'Imported post' } + }, +); +``` +```rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; +use appwrite::id::ID; +use serde_json::json; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); + client.set_project("<PROJECT_ID>"); + client.set_key("<API_KEY>"); + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.create_document( + "<DATABASE_ID>", + "<COLLECTION_ID>", + ID::unique(), + json!({ + "$createdAt": "<ORIGINAL_CREATED_AT_ISO>", + "$updatedAt": "<LAST_MODIFIED_ISO>", + "embeddings": [0.12, 0.84, 0.33, 0.57], + "metadata": { "title": "Imported post" } + }), + None, // permissions (optional) + ).await?; + + println!("Created: {:?}", result); + Ok(()) +} +``` +{% /multicode %} + +## Backdating records {% #backdating %} +For historical data entry or when creating records that represent past events: + +{% multicode %} +```server-nodejs +await vectorsDB.createDocument({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: sdk.ID.unique(), + data: { + '$createdAt': '2023-12-31T23:59:59.000Z', + '$updatedAt': '2023-12-31T23:59:59.000Z', + embeddings: [0.5, 0.5, 0.5, 0.5], + metadata: { type: 'year-end-bonus', amount: 1000 } + } +}); +``` +```server-php +$vectorsDB->createDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: ID::unique(), + data: [ + '$createdAt' => '2023-12-31T23:59:59.000Z', + '$updatedAt' => '2023-12-31T23:59:59.000Z', + 'embeddings' => [0.5, 0.5, 0.5, 0.5], + 'metadata' => ['type' => 'year-end-bonus', 'amount' => 1000] + ] +); +``` +```server-swift +let _ = try await vectorsDB.createDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: ID.unique(), + data: [ + "$createdAt": "2023-12-31T23:59:59.000Z", + "$updatedAt": "2023-12-31T23:59:59.000Z", + "embeddings": [0.5, 0.5, 0.5, 0.5], + "metadata": ["type": "year-end-bonus", "amount": 1000] + ] +) +``` +```server-python +vectors_db.create_document( + database_id='<DATABASE_ID>', + collection_id='<COLLECTION_ID>', + document_id=ID.unique(), + data={ + '$createdAt': '2023-12-31T23:59:59.000Z', + '$updatedAt': '2023-12-31T23:59:59.000Z', + 'embeddings': [0.5, 0.5, 0.5, 0.5], + 'metadata': { 'type': 'year-end-bonus', 'amount': 1000 } + } +) +``` +```server-ruby +vectors_db.create_document( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + document_id: ID.unique(), + data: { + '$createdAt' => '2023-12-31T23:59:59.000Z', + '$updatedAt' => '2023-12-31T23:59:59.000Z', + 'embeddings' => [0.5, 0.5, 0.5, 0.5], + 'metadata' => { 'type' => 'year-end-bonus', 'amount' => 1000 } + } +) +``` +```server-dotnet +await vectorsDB.CreateDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: ID.Unique(), + data: new Dictionary<string, object> + { + ["$createdAt"] = "2023-12-31T23:59:59.000Z", + ["$updatedAt"] = "2023-12-31T23:59:59.000Z", + ["embeddings"] = new List<double> { 0.5, 0.5, 0.5, 0.5 }, + ["metadata"] = new Dictionary<string, object> { ["type"] = "year-end-bonus", ["amount"] = 1000 } + } +); +``` +```server-dart +await vectorsDB.createDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: ID.unique(), + data: { + '\$createdAt': '2023-12-31T23:59:59.000Z', + '\$updatedAt': '2023-12-31T23:59:59.000Z', + 'embeddings': [0.5, 0.5, 0.5, 0.5], + 'metadata': { 'type': 'year-end-bonus', 'amount': 1000 } + }, +); +``` +```rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; +use appwrite::id::ID; +use serde_json::json; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); + client.set_project("<PROJECT_ID>"); + client.set_key("<API_KEY>"); + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.create_document( + "<DATABASE_ID>", + "<COLLECTION_ID>", + ID::unique(), + json!({ + "$createdAt": "2023-12-31T23:59:59.000Z", + "$updatedAt": "2023-12-31T23:59:59.000Z", + "embeddings": [0.5, 0.5, 0.5, 0.5], + "metadata": { "type": "year-end-bonus", "amount": 1000 } + }), + None, // permissions (optional) + ).await?; + + println!("Created: {:?}", result); + Ok(()) +} +``` +{% /multicode %} + +## Synchronization {% #synchronization %} +When synchronizing data between systems while maintaining timestamp consistency: + +{% multicode %} +```server-nodejs +await vectorsDB.upsertDocument({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID_OR_NEW_ID>', + data: { + '$updatedAt': '<EXTERNAL_LAST_MODIFIED_ISO>', + embeddings: [0.6, 0.6, 0.6, 0.6], + metadata: { profile: 'external' } + } +}); +``` +```server-php +$vectorsDB->upsertDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID_OR_NEW_ID>', + data: [ + '$updatedAt' => '<EXTERNAL_LAST_MODIFIED_ISO>', + 'embeddings' => [0.6, 0.6, 0.6, 0.6], + 'metadata' => ['profile' => 'external'] + ] +); +``` +```server-swift +let _ = try await vectorsDB.upsertDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: "<DOCUMENT_ID_OR_NEW_ID>", + data: [ + "$updatedAt": "<EXTERNAL_LAST_MODIFIED_ISO>", + "embeddings": [0.6, 0.6, 0.6, 0.6], + "metadata": ["profile": "external"] + ] +) +``` +```server-python +vectors_db.upsert_document( + database_id='<DATABASE_ID>', + collection_id='<COLLECTION_ID>', + document_id='<DOCUMENT_ID_OR_NEW_ID>', + data={ + '$updatedAt': '<EXTERNAL_LAST_MODIFIED_ISO>', + 'embeddings': [0.6, 0.6, 0.6, 0.6], + 'metadata': { 'profile': 'external' } + } +) +``` +```server-ruby +vectors_db.upsert_document( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + document_id: '<DOCUMENT_ID_OR_NEW_ID>', + data: { + '$updatedAt' => '<EXTERNAL_LAST_MODIFIED_ISO>', + 'embeddings' => [0.6, 0.6, 0.6, 0.6], + 'metadata' => { 'profile' => 'external' } + } +) +``` +```server-dotnet +await vectorsDB.UpsertDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: "<DOCUMENT_ID_OR_NEW_ID>", + data: new Dictionary<string, object> + { + ["$updatedAt"] = "<EXTERNAL_LAST_MODIFIED_ISO>", + ["embeddings"] = new List<double> { 0.6, 0.6, 0.6, 0.6 }, + ["metadata"] = new Dictionary<string, object> { ["profile"] = "external" } + } +); +``` +```server-dart +await vectorsDB.upsertDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID_OR_NEW_ID>', + data: { + '\$updatedAt': '<EXTERNAL_LAST_MODIFIED_ISO>', + 'embeddings': [0.6, 0.6, 0.6, 0.6], + 'metadata': { 'profile': 'external' } + }, +); +``` +```rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; +use serde_json::json; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); + client.set_project("<PROJECT_ID>"); + client.set_key("<API_KEY>"); + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.upsert_document( + "<DATABASE_ID>", + "<COLLECTION_ID>", + "<DOCUMENT_ID_OR_NEW_ID>", + Some(json!({ + "$updatedAt": "<EXTERNAL_LAST_MODIFIED_ISO>", + "embeddings": [0.6, 0.6, 0.6, 0.6], + "metadata": { "profile": "external" } + })), + None, // permissions (optional) + None, // transactionId (optional) + ).await?; + + println!("Upserted: {:?}", result); + Ok(()) +} +``` +{% /multicode %} + +{% info title="Timestamp format and usage" %} +- Values must be valid ISO 8601 date-time strings (UTC recommended). Using `toISOString()` (JavaScript) or `datetime.isoformat()` (Python) is a good default. +- You can set either or both attributes as needed. If omitted, Appwrite sets them automatically. +{% /info %} diff --git a/src/routes/docs/products/databases/vectorsdb/transactions/+page.markdoc b/src/routes/docs/products/databases/vectorsdb/transactions/+page.markdoc new file mode 100644 index 00000000000..00dfdfb011e --- /dev/null +++ b/src/routes/docs/products/databases/vectorsdb/transactions/+page.markdoc @@ -0,0 +1,1240 @@ +--- +layout: article +title: Transactions +description: Stage multiple VectorsDB operations and commit them atomically. Group changes across databases and collections with ordering, isolation, and conflict detection. +--- + +Transactions let you stage multiple database operations and apply them together, atomically. Use transactions to keep related changes consistent, even when they span multiple databases and collections. + +# How transactions work {% #how-transactions-work %} + +1. Call the [createTransaction](#create-a-transaction) method to create a transaction. This will return a transaction model, including its ID. +2. Stage operations by passing the `transactionId` parameter to supported document, bulk, and atomic numeric methods. You can stage many operations at once with the [createOperations](#create-operations) method. +3. Call the [updateTransaction](#commit-or-rollback) method to commit or roll back. + +On commit, Appwrite replays all staged logs in order inside a real database transaction. Staged operations see earlier staged changes (read your own writes). If any affected document changed outside your transaction, the commit fails with a conflict. + +{% info title="Scope and limitations" %} +You can stage operations across any database and collection within the same transaction. Schema operations (for example, creating or deleting indexes) are not included in transactions. +{% /info %} + +# Limits {% #limits %} + +The maximum number of operations you can stage per transaction depends on your plan: + +| Plan | Max operations per transaction | +|------|-------------------------------| +| Free | 100 | +| Pro | 1,000 | + +# Create a transaction {% #create-a-transaction %} + +Call the `createTransaction` method to begin. It returns a transaction model that includes `$id`. Pass this ID as `transactionId` to subsequent operations. Appwrite [Server SDKs](/docs/sdks#server) require an [API key](/docs/advanced/platform/api-keys). + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const tx = await vectorsDB.createTransaction(); +// tx.$id is your transactionId +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const tx = await vectorsDB.createTransaction(); +// tx.$id is your transactionId +``` +```php +<?php + +use Appwrite\Client; +use Appwrite\Services\VectorsDB; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('<YOUR_PROJECT_ID>') // Your project ID + ->setKey('<YOUR_API_KEY>'); // Your secret API key + +$vectorsDB = new VectorsDB($client); + +$tx = $vectorsDB->createTransaction(); +// $tx['$id'] is your transactionId +``` +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('<YOUR_PROJECT_ID>') # Your project ID +client.set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB(client) + +tx = vectors_db.create_transaction() +# tx['$id'] is your transactionId +``` +```ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('<YOUR_PROJECT_ID>') # Your project ID + .set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB.new(client) + +tx = vectors_db.create_transaction +# tx['$id'] is your transactionId +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("<YOUR_PROJECT_ID>") // Your project ID + .SetKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +var tx = await vectorsDB.CreateTransaction(); +// tx.Id is your transactionId +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +VectorsDB vectorsDB = VectorsDB(client); + +final tx = await vectorsDB.createTransaction(); +// tx.$id is your transactionId +``` +```kotlin +import io.appwrite.Client +import io.appwrite.services.VectorsDB + +val client = Client(context) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +val vectorsDB = VectorsDB(client) + +val tx = vectorsDB.createTransaction() +// tx.id is your transactionId +``` +```java +import io.appwrite.Client; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.VectorsDB; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +vectorsDB.createTransaction(new CoroutineCallback<>((tx, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(tx); +})); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +let vectorsDB = VectorsDB(client) + +let tx = try await vectorsDB.createTransaction() +// tx.id is your transactionId +``` +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + let tx = vectors_db.create_transaction(None).await?; + // tx.id is your transaction_id + + Ok(()) +} +``` +```bash +appwrite vectors-db create-transaction +``` +{% /multicode %} + +# Stage operations {% #stage-operations %} + +Add the `transactionId` parameter to supported methods to stage them instead of immediately persisting. + +When you pass `transactionId`, Appwrite writes the operation to an internal staging area. The target collection is not modified until you commit the transaction. + +## Stage single operations {% #stage-single-operations %} + +Update, upsert, and delete operations accept `transactionId`, as well as their bulk versions (`updateDocuments`, `upsertDocuments`, `deleteDocuments`). To stage the first write to a brand new document, use `upsertDocument` with `transactionId`. + +{% multicode %} +```server-nodejs +// Update inside a transaction +await vectorsDB.updateDocument({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + data: { metadata: { title: 'Hamlet', year: 1602 } }, + transactionId: tx.$id +}); + +// Delete inside a transaction +await vectorsDB.deleteDocument({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + transactionId: tx.$id +}); +``` +```deno +// Update inside a transaction +await vectorsDB.updateDocument({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + data: { metadata: { title: 'Hamlet', year: 1602 } }, + transactionId: tx.$id +}); + +// Delete inside a transaction +await vectorsDB.deleteDocument({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + transactionId: tx.$id +}); +``` +```php +// Update inside a transaction +$vectorsDB->updateDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + data: ['metadata' => ['title' => 'Hamlet', 'year' => 1602]], + transactionId: $tx['$id'] +); + +// Delete inside a transaction +$vectorsDB->deleteDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + transactionId: $tx['$id'] +); +``` +```python +# Update inside a transaction +vectors_db.update_document( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>', + document_id = '<DOCUMENT_ID>', + data = { "metadata": { "title": "Hamlet", "year": 1602 } }, + transaction_id = tx['$id'] +) + +# Delete inside a transaction +vectors_db.delete_document( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>', + document_id = '<DOCUMENT_ID>', + transaction_id = tx['$id'] +) +``` +```ruby +# Update inside a transaction +vectors_db.update_document( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + document_id: '<DOCUMENT_ID>', + data: { "metadata" => { "title" => "Hamlet", "year" => 1602 } }, + transaction_id: tx['$id'] +) + +# Delete inside a transaction +vectors_db.delete_document( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + document_id: '<DOCUMENT_ID>', + transaction_id: tx['$id'] +) +``` +```csharp +// Update inside a transaction +await vectorsDB.UpdateDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: "<DOCUMENT_ID>", + data: new Dictionary<string, object> { + { "metadata", new Dictionary<string, object> { { "title", "Hamlet" }, { "year", 1602 } } } + }, + transactionId: tx.Id +); + +// Delete inside a transaction +await vectorsDB.DeleteDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: "<DOCUMENT_ID>", + transactionId: tx.Id +); +``` +```dart +// Update inside a transaction +await vectorsDB.updateDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + data: { "metadata": { "title": "Hamlet", "year": 1602 } }, + transactionId: tx.$id +); + +// Delete inside a transaction +await vectorsDB.deleteDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + transactionId: tx.$id +); +``` +```kotlin +// Update inside a transaction +vectorsDB.updateDocument( + databaseId = "<DATABASE_ID>", + collectionId = "<COLLECTION_ID>", + documentId = "<DOCUMENT_ID>", + data = mapOf("metadata" to mapOf("title" to "Hamlet", "year" to 1602)), + transactionId = tx.id +) + +// Delete inside a transaction +vectorsDB.deleteDocument( + databaseId = "<DATABASE_ID>", + collectionId = "<COLLECTION_ID>", + documentId = "<DOCUMENT_ID>", + transactionId = tx.id +) +``` +```java +// Update inside a transaction (asynchronous) +vectorsDB.updateDocument( + "<DATABASE_ID>", + "<COLLECTION_ID>", + "<DOCUMENT_ID>", + Map.of("metadata", Map.of("title", "Hamlet", "year", 1602)), + listOf(), + "<TRANSACTION_ID>", + new CoroutineCallback<>((document, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(document); + }) +); +``` +```swift +// Update inside a transaction +try await vectorsDB.updateDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: "<DOCUMENT_ID>", + data: ["metadata": ["title": "Hamlet", "year": 1602]], + transactionId: tx.id +) + +// Delete inside a transaction +try await vectorsDB.deleteDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: "<DOCUMENT_ID>", + transactionId: tx.id +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; +use serde_json::json; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + let tx = vectors_db.create_transaction(None).await?; + + // Update inside a transaction + vectors_db.update_document( + "<DATABASE_ID>", + "<COLLECTION_ID>", + "<DOCUMENT_ID>", + Some(json!({ "metadata": { "title": "Hamlet", "year": 1602 } })), + None, + Some(&tx.id), + ).await?; + + // Delete inside a transaction + vectors_db.delete_document( + "<DATABASE_ID>", + "<COLLECTION_ID>", + "<DOCUMENT_ID>", + Some(&tx.id), + ).await?; + + Ok(()) +} +``` +```bash +appwrite vectors-db update-document \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --document-id <DOCUMENT_ID> \ + --data '{ "metadata": { "title": "Hamlet", "year": 1602 } }' \ + --transaction-id <TRANSACTION_ID> +``` +{% /multicode %} + +You can read uncommitted changes back inside the same transaction by passing `transactionId` to `getDocument`. A plain read without `transactionId` still returns the committed document. + +{% multicode %} +```server-nodejs +// Read your own staged write +const staged = await vectorsDB.getDocument({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + transactionId: tx.$id +}); +``` +```deno +// Read your own staged write +const staged = await vectorsDB.getDocument({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + transactionId: tx.$id +}); +``` +```php +// Read your own staged write +$staged = $vectorsDB->getDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + transactionId: $tx['$id'] +); +``` +```python +# Read your own staged write +staged = vectors_db.get_document( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>', + document_id = '<DOCUMENT_ID>', + transaction_id = tx['$id'] +) +``` +```ruby +# Read your own staged write +staged = vectors_db.get_document( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + document_id: '<DOCUMENT_ID>', + transaction_id: tx['$id'] +) +``` +```csharp +// Read your own staged write +var staged = await vectorsDB.GetDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: "<DOCUMENT_ID>", + transactionId: tx.Id +); +``` +```dart +// Read your own staged write +final staged = await vectorsDB.getDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID>', + transactionId: tx.$id +); +``` +```kotlin +// Read your own staged write +val staged = vectorsDB.getDocument( + databaseId = "<DATABASE_ID>", + collectionId = "<COLLECTION_ID>", + documentId = "<DOCUMENT_ID>", + transactionId = tx.id +) +``` +```java +// Read your own staged write (asynchronous) +vectorsDB.getDocument( + "<DATABASE_ID>", + "<COLLECTION_ID>", + "<DOCUMENT_ID>", + listOf(), + "<TRANSACTION_ID>", + new CoroutineCallback<>((document, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(document); + }) +); +``` +```swift +// Read your own staged write +let staged = try await vectorsDB.getDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: "<DOCUMENT_ID>", + transactionId: tx.id +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + let tx = vectors_db.create_transaction(None).await?; + + // Read your own staged write + let staged = vectors_db.get_document( + "<DATABASE_ID>", + "<COLLECTION_ID>", + "<DOCUMENT_ID>", + None, + Some(&tx.id), + ).await?; + + Ok(()) +} +``` +```bash +appwrite vectors-db get-document \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --document-id <DOCUMENT_ID> \ + --transaction-id <TRANSACTION_ID> +``` +{% /multicode %} + +## Stage many with createOperations {% #create-operations %} + +Use the `createOperations` method to stage multiple operations across databases and collections in a single request. Provide an array of operation objects: + +```json +[ + { + "action": "create|update|upsert|increment|decrement|delete|bulkCreate|bulkUpdate|bulkUpsert|bulkDelete", + "databaseId": "<DATABASE_ID>", + "collectionId": "<COLLECTION_ID>", + "documentId": "<DOCUMENT_ID>", + "data": {} + } +] +``` + +For `create`, `update`, and `upsert` actions, pass the document `data` (an `embeddings` vector and optional `metadata`). For `delete`, the `documentId` is enough. + +{% multicode %} +```server-nodejs +// Stage multiple operations at once +await vectorsDB.createOperations({ + transactionId: tx.$id, + operations: [ + { + action: 'update', + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID_1>', + data: { metadata: { title: 'Macbeth' } } + }, + { + action: 'delete', + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID_2>' + } + ] +}); +``` +```deno +// Stage multiple operations at once +await vectorsDB.createOperations({ + transactionId: tx.$id, + operations: [ + { + action: 'update', + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID_1>', + data: { metadata: { title: 'Macbeth' } } + }, + { + action: 'delete', + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: '<DOCUMENT_ID_2>' + } + ] +}); +``` +```php +$vectorsDB->createOperations( + transactionId: $tx['$id'], + operations: [ + [ + 'action' => 'update', + 'databaseId' => '<DATABASE_ID>', + 'collectionId' => '<COLLECTION_ID>', + 'documentId' => '<DOCUMENT_ID_1>', + 'data' => [ 'metadata' => [ 'title' => 'Macbeth' ] ] + ], + [ + 'action' => 'delete', + 'databaseId' => '<DATABASE_ID>', + 'collectionId' => '<COLLECTION_ID>', + 'documentId' => '<DOCUMENT_ID_2>' + ] + ] +); +``` +```python +vectors_db.create_operations( + transaction_id = tx['$id'], + operations = [ + { + 'action': 'update', + 'databaseId': '<DATABASE_ID>', + 'collectionId': '<COLLECTION_ID>', + 'documentId': '<DOCUMENT_ID_1>', + 'data': { 'metadata': { 'title': 'Macbeth' } } + }, + { + 'action': 'delete', + 'databaseId': '<DATABASE_ID>', + 'collectionId': '<COLLECTION_ID>', + 'documentId': '<DOCUMENT_ID_2>' + } + ] +) +``` +```ruby +vectors_db.create_operations( + transaction_id: tx['$id'], + operations: [ + { + 'action' => 'update', + 'databaseId' => '<DATABASE_ID>', + 'collectionId' => '<COLLECTION_ID>', + 'documentId' => '<DOCUMENT_ID_1>', + 'data' => { 'metadata' => { 'title' => 'Macbeth' } } + }, + { + 'action' => 'delete', + 'databaseId' => '<DATABASE_ID>', + 'collectionId' => '<COLLECTION_ID>', + 'documentId' => '<DOCUMENT_ID_2>' + } + ] +) +``` +```csharp +await vectorsDB.CreateOperations( + transactionId: tx.Id, + operations: new List<object> + { + new Dictionary<string, object> + { + ["action"] = "update", + ["databaseId"] = "<DATABASE_ID>", + ["collectionId"] = "<COLLECTION_ID>", + ["documentId"] = "<DOCUMENT_ID_1>", + ["data"] = new Dictionary<string, object> { + ["metadata"] = new Dictionary<string, object> { ["title"] = "Macbeth" } + } + }, + new Dictionary<string, object> + { + ["action"] = "delete", + ["databaseId"] = "<DATABASE_ID>", + ["collectionId"] = "<COLLECTION_ID>", + ["documentId"] = "<DOCUMENT_ID_2>" + } + } +); +``` +```dart +await vectorsDB.createOperations( + transactionId: tx.$id, + operations: [ + { + 'action': 'update', + 'databaseId': '<DATABASE_ID>', + 'collectionId': '<COLLECTION_ID>', + 'documentId': '<DOCUMENT_ID_1>', + 'data': { 'metadata': { 'title': 'Macbeth' } } + }, + { + 'action': 'delete', + 'databaseId': '<DATABASE_ID>', + 'collectionId': '<COLLECTION_ID>', + 'documentId': '<DOCUMENT_ID_2>' + } + ] +); +``` +```kotlin +vectorsDB.createOperations( + transactionId = tx.id, + operations = listOf( + mapOf( + "action" to "update", + "databaseId" to "<DATABASE_ID>", + "collectionId" to "<COLLECTION_ID>", + "documentId" to "<DOCUMENT_ID_1>", + "data" to mapOf("metadata" to mapOf("title" to "Macbeth")) + ), + mapOf( + "action" to "delete", + "databaseId" to "<DATABASE_ID>", + "collectionId" to "<COLLECTION_ID>", + "documentId" to "<DOCUMENT_ID_2>" + ) + ) +) +``` +```java +// Stage multiple operations at once (asynchronous) +List<Map<String, Object>> operations = Arrays.asList( + Map.of( + "action", "update", + "databaseId", "<DATABASE_ID>", + "collectionId", "<COLLECTION_ID>", + "documentId", "<DOCUMENT_ID_1>", + "data", Map.of("metadata", Map.of("title", "Macbeth")) + ), + Map.of( + "action", "delete", + "databaseId", "<DATABASE_ID>", + "collectionId", "<COLLECTION_ID>", + "documentId", "<DOCUMENT_ID_2>" + ) +); + +vectorsDB.createOperations( + "<TRANSACTION_ID>", + operations, + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +try await vectorsDB.createOperations( + transactionId: tx.id, + operations: [ + [ + "action": "update", + "databaseId": "<DATABASE_ID>", + "collectionId": "<COLLECTION_ID>", + "documentId": "<DOCUMENT_ID_1>", + "data": ["metadata": ["title": "Macbeth"]] + ], + [ + "action": "delete", + "databaseId": "<DATABASE_ID>", + "collectionId": "<COLLECTION_ID>", + "documentId": "<DOCUMENT_ID_2>" + ] + ] +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; +use serde_json::json; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + let tx = vectors_db.create_transaction(None).await?; + + // Stage multiple operations at once + vectors_db.create_operations( + &tx.id, + Some(vec![ + json!({ + "action": "update", + "databaseId": "<DATABASE_ID>", + "collectionId": "<COLLECTION_ID>", + "documentId": "<DOCUMENT_ID_1>", + "data": { "metadata": { "title": "Macbeth" } } + }), + json!({ + "action": "delete", + "databaseId": "<DATABASE_ID>", + "collectionId": "<COLLECTION_ID>", + "documentId": "<DOCUMENT_ID_2>" + }), + ]), + ).await?; + + Ok(()) +} +``` +{% /multicode %} + +# Commit or roll back {% #commit-or-rollback %} + +When you are done staging operations, call the `updateTransaction` method to finalize the transaction. Set `commit` to `true` to apply the staged operations, or `rollback` to `true` to discard them. + +{% multicode %} +```server-nodejs +// Commit +await vectorsDB.updateTransaction({ + transactionId: tx.$id, + commit: true +}); + +// Or roll back +await vectorsDB.updateTransaction({ + transactionId: tx.$id, + rollback: true +}); +``` +```deno +// Commit +await vectorsDB.updateTransaction({ + transactionId: tx.$id, + commit: true +}); + +// Or roll back +await vectorsDB.updateTransaction({ + transactionId: tx.$id, + rollback: true +}); +``` +```php +// Commit +$vectorsDB->updateTransaction( + transactionId: $tx['$id'], + commit: true +); + +// Roll back +$vectorsDB->updateTransaction( + transactionId: $tx['$id'], + rollback: true +); +``` +```python +# Commit +vectors_db.update_transaction( + transaction_id = tx['$id'], + commit = True +) + +# Roll back +vectors_db.update_transaction( + transaction_id = tx['$id'], + rollback = True +) +``` +```ruby +# Commit +vectors_db.update_transaction( + transaction_id: tx['$id'], + commit: true +) + +# Roll back +vectors_db.update_transaction( + transaction_id: tx['$id'], + rollback: true +) +``` +```csharp +// Commit +await vectorsDB.UpdateTransaction( + transactionId: tx.Id, + commit: true +); + +// Roll back +await vectorsDB.UpdateTransaction( + transactionId: tx.Id, + rollback: true +); +``` +```dart +// Commit +await vectorsDB.updateTransaction( + transactionId: tx.$id, + commit: true +); + +// Roll back +await vectorsDB.updateTransaction( + transactionId: tx.$id, + rollback: true +); +``` +```kotlin +// Commit +vectorsDB.updateTransaction( + transactionId = tx.id, + commit = true +) + +// Roll back +vectorsDB.updateTransaction( + transactionId = tx.id, + rollback = true +) +``` +```java +// Commit (asynchronous) +vectorsDB.updateTransaction( + "<TRANSACTION_ID>", + true, + false, + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); + +// Roll back (asynchronous) +vectorsDB.updateTransaction( + "<TRANSACTION_ID>", + false, + true, + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +// Commit +try await vectorsDB.updateTransaction( + transactionId: tx.id, + commit: true +) + +// Roll back +try await vectorsDB.updateTransaction( + transactionId: tx.id, + rollback: true +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + // Commit + vectors_db.update_transaction( + "<TRANSACTION_ID>", + Some(true), + None, + ).await?; + + // Roll back + vectors_db.update_transaction( + "<TRANSACTION_ID>", + None, + Some(true), + ).await?; + + Ok(()) +} +``` +```bash +# Commit +appwrite vectors-db update-transaction \ + --transaction-id <TRANSACTION_ID> \ + --commit true + +# Roll back +appwrite vectors-db update-transaction \ + --transaction-id <TRANSACTION_ID> \ + --rollback true +``` +{% /multicode %} + +# Inspect and delete transactions {% #inspect-and-delete %} + +Use `getTransaction` to check a transaction's status and operation count, `listTransactions` to list transactions across all databases, and `deleteTransaction` to discard a transaction without committing it. + +{% multicode %} +```server-nodejs +// Get one transaction +const tx = await vectorsDB.getTransaction({ transactionId: '<TRANSACTION_ID>' }); + +// List transactions +const list = await vectorsDB.listTransactions(); + +// Delete a transaction +await vectorsDB.deleteTransaction({ transactionId: '<TRANSACTION_ID>' }); +``` +```deno +// Get one transaction +const tx = await vectorsDB.getTransaction({ transactionId: '<TRANSACTION_ID>' }); + +// List transactions +const list = await vectorsDB.listTransactions(); + +// Delete a transaction +await vectorsDB.deleteTransaction({ transactionId: '<TRANSACTION_ID>' }); +``` +```php +// Get one transaction +$tx = $vectorsDB->getTransaction(transactionId: '<TRANSACTION_ID>'); + +// List transactions +$list = $vectorsDB->listTransactions(); + +// Delete a transaction +$vectorsDB->deleteTransaction(transactionId: '<TRANSACTION_ID>'); +``` +```python +# Get one transaction +tx = vectors_db.get_transaction(transaction_id = '<TRANSACTION_ID>') + +# List transactions +list = vectors_db.list_transactions() + +# Delete a transaction +vectors_db.delete_transaction(transaction_id = '<TRANSACTION_ID>') +``` +```ruby +# Get one transaction +tx = vectors_db.get_transaction(transaction_id: '<TRANSACTION_ID>') + +# List transactions +list = vectors_db.list_transactions + +# Delete a transaction +vectors_db.delete_transaction(transaction_id: '<TRANSACTION_ID>') +``` +```csharp +// Get one transaction +var tx = await vectorsDB.GetTransaction(transactionId: "<TRANSACTION_ID>"); + +// List transactions +var list = await vectorsDB.ListTransactions(); + +// Delete a transaction +await vectorsDB.DeleteTransaction(transactionId: "<TRANSACTION_ID>"); +``` +```dart +// Get one transaction +final tx = await vectorsDB.getTransaction(transactionId: '<TRANSACTION_ID>'); + +// List transactions +final list = await vectorsDB.listTransactions(); + +// Delete a transaction +await vectorsDB.deleteTransaction(transactionId: '<TRANSACTION_ID>'); +``` +```kotlin +// Get one transaction +val tx = vectorsDB.getTransaction(transactionId = "<TRANSACTION_ID>") + +// List transactions +val list = vectorsDB.listTransactions() + +// Delete a transaction +vectorsDB.deleteTransaction(transactionId = "<TRANSACTION_ID>") +``` +```java +// Get one transaction (asynchronous) +vectorsDB.getTransaction( + "<TRANSACTION_ID>", + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); + +// List transactions (asynchronous) +vectorsDB.listTransactions(new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); +})); + +// Delete a transaction (asynchronous) +vectorsDB.deleteTransaction( + "<TRANSACTION_ID>", + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +// Get one transaction +let tx = try await vectorsDB.getTransaction(transactionId: "<TRANSACTION_ID>") + +// List transactions +let list = try await vectorsDB.listTransactions() + +// Delete a transaction +try await vectorsDB.deleteTransaction(transactionId: "<TRANSACTION_ID>") +``` +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + // Get one transaction + let tx = vectors_db.get_transaction("<TRANSACTION_ID>").await?; + + // List transactions + let list = vectors_db.list_transactions(None).await?; + + // Delete a transaction + vectors_db.delete_transaction("<TRANSACTION_ID>").await?; + + Ok(()) +} +``` +```bash +# Get one transaction +appwrite vectors-db get-transaction \ + --transaction-id <TRANSACTION_ID> + +# List transactions +appwrite vectors-db list-transactions + +# Delete a transaction +appwrite vectors-db delete-transaction \ + --transaction-id <TRANSACTION_ID> +``` +{% /multicode %} + +# Handle conflicts {% #handle-conflicts %} + +On commit, Appwrite verifies that documents affected by your transaction haven't changed externally since they were staged. If a conflicting change is detected, the commit fails with a conflict error. Resolve the conflict (for example, refetch and re-stage) and try again. + +{% info title="Best practices" %} +Keep transactions short-lived to reduce the likelihood of conflicts. Stage related updates in the order they must be applied. Prefer `createOperations` when you need to stage many changes across multiple collections. +{% /info %} + +{% arrow_link href="/docs/references" %} +Explore the API references +{% /arrow_link %} diff --git a/src/routes/docs/products/databases/vectorsdb/vector-search/+page.markdoc b/src/routes/docs/products/databases/vectorsdb/vector-search/+page.markdoc new file mode 100644 index 00000000000..a663dcb0458 --- /dev/null +++ b/src/routes/docs/products/databases/vectorsdb/vector-search/+page.markdoc @@ -0,0 +1,556 @@ +--- +layout: article +title: Vector search +description: Run similarity search over your documents with Appwrite VectorsDB. Create an HNSW index on the embeddings field and rank documents by cosine, dot product, or Euclidean distance. +--- +Vector search finds the documents whose `embeddings` are closest to a query vector. +Instead of matching exact values, it ranks documents by similarity, so you can build features like semantic search, recommendations, and retrieval for AI applications. + +There are two steps: create an [index](/docs/products/databases/vectorsdb/collections) on the `embeddings` field so searches are fast, then pass a vector query to `listDocuments` to get documents ranked by similarity. + +# Create an index {% #create-an-index %} +Before you search, create an HNSW index on the `embeddings` field with `createIndex`. HNSW (Hierarchical Navigable Small World) is an approximate nearest neighbor index that keeps similarity search fast as your collection grows. + +The index `type` decides how similarity is measured. Use the `VectorsDBIndexType` enum to pick one: + +| Index type | Enum | Use when | +| --- | --- | --- | +| `hnsw_cosine` | `VectorsDBIndexType.HnswCosine` | You care about the direction of the vectors, not their magnitude. A common default for text embeddings. | +| `hnsw_dot` | `VectorsDBIndexType.HnswDot` | You want the dot product, which factors in both direction and magnitude. | +| `hnsw_euclidean` | `VectorsDBIndexType.HnswEuclidean` | You want the straight-line distance between vectors. | + +Match the index type to the search query you plan to run. A `hnsw_cosine` index serves `Query.vectorCosine` searches, `hnsw_dot` serves `Query.vectorDot`, and `hnsw_euclidean` serves `Query.vectorEuclidean`. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.createIndex({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + key: 'embeddings_index', + type: sdk.VectorsDBIndexType.HnswCosine, + attributes: ['embeddings'] +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.createIndex({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + key: 'embeddings_index', + type: sdk.VectorsDBIndexType.HnswCosine, + attributes: ['embeddings'] +}); +``` +```php +<?php + +use Appwrite\Client; +use Appwrite\Services\VectorsDB; +use Appwrite\Enums\VectorsDBIndexType; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('<YOUR_PROJECT_ID>') // Your project ID + ->setKey('<YOUR_API_KEY>'); // Your secret API key + +$vectorsDB = new VectorsDB($client); + +$result = $vectorsDB->createIndex( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + key: 'embeddings_index', + type: VectorsDBIndexType::HNSWCOSINE(), + attributes: ['embeddings'] +); +``` +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB +from appwrite.enums import VectorsDBIndexType + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('<YOUR_PROJECT_ID>') # Your project ID +client.set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB(client) + +result = vectors_db.create_index( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>', + key = 'embeddings_index', + type = VectorsDBIndexType.HNSW_COSINE, + attributes = ['embeddings'] +) +``` +```ruby +require 'appwrite' + +include Appwrite +include Appwrite::Enums + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('<YOUR_PROJECT_ID>') # Your project ID + .set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB.new(client) + +result = vectors_db.create_index( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + key: 'embeddings_index', + type: VectorsDBIndexType::HNSW_COSINE, + attributes: ['embeddings'] +) +``` +```csharp +using Appwrite; +using Appwrite.Enums; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("<YOUR_PROJECT_ID>") // Your project ID + .SetKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +Index result = await vectorsDB.CreateIndex( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + key: "embeddings_index", + type: VectorsDBIndexType.HnswCosine, + attributes: new List<string> { "embeddings" } +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; +import 'package:dart_appwrite/enums.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +VectorsDB vectorsDB = VectorsDB(client); + +Index result = await vectorsDB.createIndex( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + key: 'embeddings_index', + type: VectorsDBIndexType.hnswCosine, + attributes: ['embeddings'], +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.enums.VectorsDBIndexType +import io.appwrite.services.VectorsDB + +val client = Client(context) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +val vectorsDB = VectorsDB(client) + +val result = vectorsDB.createIndex( + databaseId = "<DATABASE_ID>", + collectionId = "<COLLECTION_ID>", + key = "embeddings_index", + type = VectorsDBIndexType.HNSW_COSINE, + attributes = listOf("embeddings"), +) +``` +```java +import io.appwrite.Client; +import io.appwrite.enums.VectorsDBIndexType; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.VectorsDB; +import java.util.List; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +vectorsDB.createIndex( + "<DATABASE_ID>", + "<COLLECTION_ID>", + "embeddings_index", + VectorsDBIndexType.HNSW_COSINE, + List.of("embeddings"), + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite +import AppwriteEnums + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +let vectorsDB = VectorsDB(client) + +let index = try await vectorsDB.createIndex( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + key: "embeddings_index", + type: .hnswCosine, + attributes: ["embeddings"] +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; +use appwrite::enums::VectorsDBIndexType; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.create_index( + "<DATABASE_ID>", + "<COLLECTION_ID>", + "embeddings_index", + VectorsDBIndexType::HnswCosine, + vec!["embeddings"], + None, // orders (optional) + None, // lengths (optional) + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite vectors-db create-index \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --key 'embeddings_index' \ + --type 'hnsw_cosine' \ + --attributes 'embeddings' +``` +{% /multicode %} + +The index is built in the background. New documents are added to the index as you create them, so you can keep writing while it builds. + +# Run a similarity search {% #run-a-similarity-search %} +To search, pass a vector query to `listDocuments`. Build the query with one of the `Query` vector methods, passing the field name `embeddings` and the query vector. The response returns documents ranked from most to least similar. + +| Query method | Use with index type | +| --- | --- | +| `Query.vectorCosine('embeddings', vector)` | `hnsw_cosine` | +| `Query.vectorDot('embeddings', vector)` | `hnsw_dot` | +| `Query.vectorEuclidean('embeddings', vector)` | `hnsw_euclidean` | + +The query vector must have the same `dimension` as the collection. You can combine the vector query with other queries, such as `Query.limit()` to cap how many results you get back. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.listDocuments({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + sdk.Query.vectorCosine('embeddings', [0.11, 0.21, 0.30, 0.40]), + sdk.Query.limit(3) + ] +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.listDocuments({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + sdk.Query.vectorCosine('embeddings', [0.11, 0.21, 0.30, 0.40]), + sdk.Query.limit(3) + ] +}); +``` +```php +<?php + +use Appwrite\Client; +use Appwrite\Services\VectorsDB; +use Appwrite\Query; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('<YOUR_PROJECT_ID>') // Your project ID + ->setKey('<YOUR_API_KEY>'); // Your secret API key + +$vectorsDB = new VectorsDB($client); + +$result = $vectorsDB->listDocuments( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + Query::vectorCosine('embeddings', [0.11, 0.21, 0.30, 0.40]), + Query::limit(3) + ] +); +``` +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB +from appwrite.query import Query + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('<YOUR_PROJECT_ID>') # Your project ID +client.set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB(client) + +result = vectors_db.list_documents( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>', + queries = [ + Query.vector_cosine('embeddings', [0.11, 0.21, 0.30, 0.40]), + Query.limit(3) + ] +) +``` +```ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('<YOUR_PROJECT_ID>') # Your project ID + .set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB.new(client) + +result = vectors_db.list_documents( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + queries: [ + Query.vector_cosine('embeddings', [0.11, 0.21, 0.30, 0.40]), + Query.limit(3) + ] +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; +using Appwrite.Queries; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("<YOUR_PROJECT_ID>") // Your project ID + .SetKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +DocumentList result = await vectorsDB.ListDocuments( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + queries: new List<string> { + Query.VectorCosine("embeddings", new List<object> { 0.11, 0.21, 0.30, 0.40 }), + Query.Limit(3) + } +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +VectorsDB vectorsDB = VectorsDB(client); + +DocumentList result = await vectorsDB.listDocuments( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + Query.vectorCosine('embeddings', [0.11, 0.21, 0.30, 0.40]), + Query.limit(3) + ], +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.Query +import io.appwrite.services.VectorsDB + +val client = Client(context) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +val vectorsDB = VectorsDB(client) + +val result = vectorsDB.listDocuments( + databaseId = "<DATABASE_ID>", + collectionId = "<COLLECTION_ID>", + queries = listOf( + Query.vectorCosine("embeddings", listOf(0.11, 0.21, 0.30, 0.40)), + Query.limit(3) + ), +) +``` +```java +import io.appwrite.Client; +import io.appwrite.Query; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.VectorsDB; +import java.util.List; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +vectorsDB.listDocuments( + "<DATABASE_ID>", + "<COLLECTION_ID>", + List.of( + Query.vectorCosine("embeddings", List.of(0.11, 0.21, 0.30, 0.40)), + Query.limit(3) + ), + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +let vectorsDB = VectorsDB(client) + +let result = try await vectorsDB.listDocuments( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + queries: [ + Query.vectorCosine("embeddings", [0.11, 0.21, 0.30, 0.40]), + Query.limit(3) + ] +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; +use appwrite::query::Query; +use serde_json::json; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.list_documents( + "<DATABASE_ID>", + "<COLLECTION_ID>", + Some(vec![ + Query::vector_cosine("embeddings", json!([0.11, 0.21, 0.30, 0.40])).to_string(), + Query::limit(3).to_string(), + ]), + None, // transaction_id + None, // total + None, // ttl + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"vectorCosine","attribute":"embeddings","values":[[0.11,0.21,0.30,0.40]]}' '{"method":"limit","values":[3]}' +``` +{% /multicode %} + +To rank by dot product or Euclidean distance instead, swap `vectorCosine` for `vectorDot` or `vectorEuclidean`, and make sure your index uses the matching type. + +{% info title="One vector query per request" %} +A single `listDocuments` call accepts at most one vector query. You can still add non-vector queries such as `Query.limit()` to the same request, but combining two vector queries in one call is not supported. +{% /info %} + +{% info title="Vector search currently works with low dimensions only" %} +Vector queries are sent on a `GET` request, and each query string is capped at 4096 characters. A serialized query vector grows with its dimension, so once a vector reaches a few hundred dimensions it pushes the query past that limit and the request is rejected with a `400 general_argument_invalid` error: *"Value must be a valid string and at least 1 chars and no longer than 4096 chars"*. The exact cutoff depends on the precision of the numbers in your vector, but in practice it falls somewhere around 200 to 270 dimensions. + +This means vector search through the SDK currently works for low-dimensional vectors only. The built-in [embedding models](/docs/products/databases/vectorsdb/embeddings) produce 384- and 768-dimensional vectors, which exceed this limit, so you cannot yet search over those embeddings directly. Keep your search vectors small enough to stay under the 4096-character limit. +{% /info %} + +# Next steps {% #next-steps %} +Vector search ranks documents by similarity. To filter those results by the data stored alongside each vector, combine search with metadata queries. + +{% arrow_link href="/docs/products/databases/vectorsdb/queries" %} +Learn about querying metadata +{% /arrow_link %} From 1739db52271574e5692fc52016045ebcbcc3bce8 Mon Sep 17 00:00:00 2001 From: Atharva Deosthale <atharva.deosthale17@gmail.com> Date: Wed, 1 Jul 2026 19:19:53 +0530 Subject: [PATCH 4/8] Add JSON import and export docs for DocumentsDB --- .optimize-cache.json | 2 + .../databases/documentsdb/+layout.svelte | 8 ++ .../documentsdb/json-exports/+page.markdoc | 96 ++++++++++++++++++ .../documentsdb/json-imports/+page.markdoc | 94 +++++++++++++++++ .../dark/documentsdb-import-export.avif | Bin 0 -> 35245 bytes .../databases/documentsdb-import-export.avif | Bin 0 -> 33739 bytes 6 files changed, 200 insertions(+) create mode 100644 src/routes/docs/products/databases/documentsdb/json-exports/+page.markdoc create mode 100644 src/routes/docs/products/databases/documentsdb/json-imports/+page.markdoc create mode 100644 static/images/docs/databases/dark/documentsdb-import-export.avif create mode 100644 static/images/docs/databases/documentsdb-import-export.avif diff --git a/.optimize-cache.json b/.optimize-cache.json index babde58ee40..1d753d17ce1 100644 --- a/.optimize-cache.json +++ b/.optimize-cache.json @@ -1449,12 +1449,14 @@ "static/images/docs/databases/dark/csv-export.png": "8d2fbffbdc4b1e6e443d61a93fe4a331ecd91c66ae1457270f51f296c406aeb9", "static/images/docs/databases/dark/csv-import.png": "bdd1e700c747e703ac75b744a8e1caa7e0704ac3439e4ed1077ee0a8e76389d3", "static/images/docs/databases/dark/databases.png": "2cc14bcda3d289c3fb77f8ee4f432d93b46bd0b9755cbf26a53fcadbca3cf32b", + "static/images/docs/databases/dark/documentsdb-import-export.png": "8e87428ef2f5698bd041d398de165ac5063aa7db951901913ec4b7b1674073bc", "static/images/docs/databases/dark/manual-backup.png": "539bdf15bf654a1a696951f4447465b286566460b311ce3db82eb010502a7e03", "static/images/docs/databases/dark/pro-policy.png": "7f74b6eae525187faa9f34a12a0804b227ba9cb2bbd9300f5e8337e9512a6f14", "static/images/docs/databases/dark/restore.png": "f2605303eba4c528bf0041b0e37bb64e61c66503b2d753716b224f66b8f62ecf", "static/images/docs/databases/dark/scale-custom-policies.png": "0013e987e9b8b917cb9be4c28048f851f2d188f3bfa5ff17a11a7ac7cf9c3ade", "static/images/docs/databases/dark/scale-policies.png": "9ca9523f2e20e9aa993f0ad933cdf1dcd12adbaa35ecb2a0b8b3d2fd65877e1f", "static/images/docs/databases/databases.png": "0278a6bc5672684653f74bcf3c0d022fdd82a08d7a7fd438b28e21bd81b5e5d5", + "static/images/docs/databases/documentsdb-import-export.png": "4456efce983bfe6aebaafde0b119801cf35173a036bd0ddd06be4a74afd14778", "static/images/docs/databases/documentsdb/backup-policy.png": "913cacbe957847f8a71efa2d2e704754e52cf9c276dce8978f6c473a9ba6595b", "static/images/docs/databases/documentsdb/backups-tab.png": "231163729496618d26863c6fa7ad88069875f78a3c320033d4bddc3c2f8da376", "static/images/docs/databases/documentsdb/create-database.png": "49ba017dcec96631a87f924b13b6b93478add7b516cc62947e87230b5a0d5de1", diff --git a/src/routes/docs/products/databases/documentsdb/+layout.svelte b/src/routes/docs/products/databases/documentsdb/+layout.svelte index 3f63cab9b0a..6d43eae7041 100644 --- a/src/routes/docs/products/databases/documentsdb/+layout.svelte +++ b/src/routes/docs/products/databases/documentsdb/+layout.svelte @@ -78,6 +78,14 @@ { label: 'Timestamp overrides', href: '/docs/products/databases/documentsdb/timestamp-overrides' + }, + { + label: 'JSON imports', + href: '/docs/products/databases/documentsdb/json-imports' + }, + { + label: 'JSON exports', + href: '/docs/products/databases/documentsdb/json-exports' } ] } diff --git a/src/routes/docs/products/databases/documentsdb/json-exports/+page.markdoc b/src/routes/docs/products/databases/documentsdb/json-exports/+page.markdoc new file mode 100644 index 00000000000..05d23aae415 --- /dev/null +++ b/src/routes/docs/products/databases/documentsdb/json-exports/+page.markdoc @@ -0,0 +1,96 @@ +--- +layout: article +title: JSON exports +description: Export documents from a DocumentsDB collection to a JSON file. Share datasets, create custom backups, or move data to another system without writing custom scripts. +--- + +Appwrite's JSON Export feature allows you to export documents from a collection to a JSON file. This is especially useful for creating custom backups, sharing data with other teams, or moving datasets to another system. + +# Export configuration {% #export-configuration %} + +Before exporting, you can configure a few options to control the contents of the output. These settings let you export exactly the data you need. + +## Select fields {% #select-fields %} + +You can choose which fields to include in your export. By default, every field is exported, but selecting specific fields creates cleaner, more focused datasets that are easier to work with. + +{% info title="Good to know" %} +System fields like `$id`, `$permissions`, `$createdAt`, and `$updatedAt` are always included in the export. +{% /info %} + +## Filter documents {% #filter-documents %} + +You can apply queries to export only the documents you need. This is especially useful when you want to export a subset of a collection for a specific use case. + +# Export format {% #export-format %} + +Each document is exported as a JSON object that includes its system fields and data fields. The output file is an array of these objects. + +An example of exported data: + +```json +[ + { + "$id": "book-1", + "$permissions": ["read(\"any\")"], + "$createdAt": "2025-08-10T12:34:56.000Z", + "$updatedAt": "2025-08-10T12:34:56.000Z", + "title": "Harry Potter and the Sorcerer's Stone", + "author": "J.K. Rowling", + "year": 1997, + "available": true + } +] +``` + +# Timestamps {% #timestamps %} + +The `$createdAt` and `$updatedAt` fields are exported in ISO 8601 format, making them compatible with most tools that consume JSON. + +# Permissions {% #permissions %} + +If document level security is enabled for your collection, the `$permissions` field contains the permission strings for each document. Permission strings are formatted as an array of role definitions. + +The roles used are API strings that can be found in the [permissions documentation](/docs/apis/rest#roles). + +# Background processing {% #background-processing %} + +Large exports run as background tasks to avoid blocking your workflow. When an export completes, you'll receive an email with a short-lived download link to retrieve your JSON file. + +This means you can start an export, close the Console, and return later to download your file. The Console displays a floating progress bar while the export is active. + +# Export documents from the Console {% #export-console %} + +{% only_dark %} +![JSON export from the collection toolbar](/images/docs/databases/dark/documentsdb-import-export.avif) +{% /only_dark %} +{% only_light %} +![JSON export from the collection toolbar](/images/docs/databases/documentsdb-import-export.avif) +{% /only_light %} + +To export documents using the Appwrite Console: + +1. Go to your project and navigate to **Databases** +2. Select your database and open the target collection +3. Click the export (download) icon in the collection toolbar +4. Configure your export options: + - Choose which fields to include (optional) + - Apply queries to filter documents (optional) +5. Start the export + +The export begins processing in the background. You'll see a progress indicator and receive an email when the export is ready to download. + +# Use cases {% #use-cases %} + +JSON exports are useful for many common workflows: + +- **Custom backups**: Archive specific data subsets for record-keeping +- **Data sharing**: Hand off datasets to other teams +- **Migration preparation**: Extract data for migration to other systems +- **Reporting**: Feed data into tools that consume JSON + +# Additional resources {% #additional-resources %} + +- [JSON imports](/docs/products/databases/documentsdb/json-imports) +- [Documents](/docs/products/databases/documentsdb/documents) +- [Database permissions](/docs/products/databases/documentsdb/permissions) diff --git a/src/routes/docs/products/databases/documentsdb/json-imports/+page.markdoc b/src/routes/docs/products/databases/documentsdb/json-imports/+page.markdoc new file mode 100644 index 00000000000..5749ebf282b --- /dev/null +++ b/src/routes/docs/products/databases/documentsdb/json-imports/+page.markdoc @@ -0,0 +1,94 @@ +--- +layout: article +title: JSON imports +description: Create documents in a DocumentsDB collection by uploading a JSON file. Seed test data, restore a dataset, or migrate from another system without writing custom scripts. +--- + +Appwrite's JSON Import feature allows you to create multiple documents in a collection by uploading a single JSON file. This is especially useful for importing existing data, seeding test environments, or migrating from other systems. + +# Prepare your JSON file {% #prepare-file %} + +Your JSON file is an array of objects, where each object becomes one document in the collection. DocumentsDB is schemaless, so each object can hold its own set of fields. + +An example of a valid JSON file: + +```json +[ + { + "title": "Harry Potter and the Sorcerer's Stone", + "author": "J.K. Rowling", + "year": 1997, + "available": true + }, + { + "title": "The Fellowship of the Ring", + "author": "J.R.R. Tolkien", + "year": 1954, + "available": true + } +] +``` + +Each object is validated before being imported. + +# Custom document IDs {% #custom-ids %} + +You can include a `$id` field on any object to set a custom document ID. If you omit it, Appwrite generates a unique ID for the document automatically. + +```json +[ + { + "$id": "book-1", + "title": "Harry Potter and the Sorcerer's Stone", + "author": "J.K. Rowling" + } +] +``` + +# Handle duplicate IDs {% #duplicate-ids %} + +When an imported document uses a `$id` that already exists in the collection, Appwrite decides what to do based on the duplicate handling you choose: + +- **Fail** (default): the import stops at the first conflicting ID. +- **Skip**: conflicting documents are ignored, and the rest are imported. +- **Overwrite**: existing documents are replaced with the imported version. + +# Permissions {% #permissions %} + +You can set document level permissions by including a `$permissions` field with an array of permission strings. Make sure document level security is enabled for your collection. + +```json +[ + { + "$id": "book-1", + "$permissions": ["read(\"any\")", "update(\"users\")", "delete(\"user:user_id\")"], + "title": "Harry Potter and the Sorcerer's Stone" + } +] +``` + +The roles used are API strings that can be found in the [permissions documentation](/docs/apis/rest#roles). + +# Import documents from the Console {% #import-console %} + +{% only_dark %} +![JSON import from the collection toolbar](/images/docs/databases/dark/documentsdb-import-export.avif) +{% /only_dark %} +{% only_light %} +![JSON import from the collection toolbar](/images/docs/databases/documentsdb-import-export.avif) +{% /only_light %} + +To import documents using the Appwrite Console: + +1. Go to your project and navigate to **Databases** +2. Select your database and open the target collection +3. Click the import (upload) icon in the collection toolbar +4. Upload a new JSON file or choose an existing file from your Storage bucket + +JSON imports run as background tasks. The Console displays a floating progress bar while the import is active. + +# Additional resources {% #additional-resources %} + +- [JSON exports](/docs/products/databases/documentsdb/json-exports) +- [Documents](/docs/products/databases/documentsdb/documents) +- [Database permissions](/docs/products/databases/documentsdb/permissions) diff --git a/static/images/docs/databases/dark/documentsdb-import-export.avif b/static/images/docs/databases/dark/documentsdb-import-export.avif new file mode 100644 index 0000000000000000000000000000000000000000..de937ff4c6a8ae6695545ea784c286fc39de878c GIT binary patch literal 35245 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 literal 0 HcmV?d00001 diff --git a/static/images/docs/databases/documentsdb-import-export.avif b/static/images/docs/databases/documentsdb-import-export.avif new file mode 100644 index 0000000000000000000000000000000000000000..9bdce2ba3bb7ea964fca78b1b16994b4961b561f GIT binary patch literal 33739 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 literal 0 HcmV?d00001 From faff2981ee64afa80baf482af45820de08eae9c3 Mon Sep 17 00:00:00 2001 From: Atharva Deosthale <atharva.deosthale17@gmail.com> Date: Wed, 1 Jul 2026 19:19:53 +0530 Subject: [PATCH 5/8] Address review feedback on DocumentsDB docs --- .../products/databases/documentsdb/backups/+page.markdoc | 7 +++---- .../databases/documentsdb/bulk-operations/+page.markdoc | 2 +- .../products/databases/documentsdb/order/+page.markdoc | 4 ++-- .../databases/documentsdb/pagination/+page.markdoc | 2 +- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/routes/docs/products/databases/documentsdb/backups/+page.markdoc b/src/routes/docs/products/databases/documentsdb/backups/+page.markdoc index a5930313c71..629bab646ce 100644 --- a/src/routes/docs/products/databases/documentsdb/backups/+page.markdoc +++ b/src/routes/docs/products/databases/documentsdb/backups/+page.markdoc @@ -1,13 +1,12 @@ --- layout: article title: Backups -description: Learn how to back up and restore your DocumentsDB databases on Appwrite Cloud, ensuring data security and seamless recovery. +description: Learn how to back up and restore your DocumentsDB databases, ensuring data security and seamless recovery. --- -Appwrite Backups enable seamless, **encrypted** database backups on Cloud. -All backups are **hot** backups, ensuring zero downtime and fast recovery. +Backups protect your DocumentsDB data by capturing a full copy of a database that you can restore later. Every backup is **encrypted** and taken as a **hot** backup, so your database keeps serving traffic with zero downtime and recovery stays fast. -{% info title="Backups are available on Appwrite Cloud for all Pro and Enterprise customers." %} +{% info title="Backups are available for all Pro and Enterprise customers." %} {% /info %} You manage backups from a database's **Backups** tab, where you can automate backups with policies or create manual backups on demand. diff --git a/src/routes/docs/products/databases/documentsdb/bulk-operations/+page.markdoc b/src/routes/docs/products/databases/documentsdb/bulk-operations/+page.markdoc index 6522e3bde64..e83d69316b4 100644 --- a/src/routes/docs/products/databases/documentsdb/bulk-operations/+page.markdoc +++ b/src/routes/docs/products/databases/documentsdb/bulk-operations/+page.markdoc @@ -4,7 +4,7 @@ title: Bulk operations description: Perform bulk operations on documents within your collections for efficient data handling. --- -Appwrite Databases supports bulk operations for documents, allowing you to create, update, or delete multiple documents in a single request. This can significantly improve performance for apps as it allows you to reduce the number of API calls needed while working with large data sets. +Appwrite DocumentsDB supports bulk operations for documents, allowing you to create, update, or delete multiple documents in a single request. This can significantly improve performance for apps as it allows you to reduce the number of API calls needed while working with large data sets. Bulk operations can only be performed via the server-side SDKs. The client-side SDKs do not support bulk operations by design to prevent abuse and protect against unexpected costs. This ensures that only trusted server environments can perform large-scale data operations. diff --git a/src/routes/docs/products/databases/documentsdb/order/+page.markdoc b/src/routes/docs/products/databases/documentsdb/order/+page.markdoc index c8dfeba16c6..cf7bb7a1f73 100644 --- a/src/routes/docs/products/databases/documentsdb/order/+page.markdoc +++ b/src/routes/docs/products/databases/documentsdb/order/+page.markdoc @@ -1,10 +1,10 @@ --- layout: article title: Order -description: Understand how to do data ordering in Appwrite Databases. Learn how to order and sort your database records for efficient data retrieval. +description: Understand how to do data ordering in Appwrite DocumentsDB. Learn how to order and sort your database records for efficient data retrieval. --- -You can order results returned by Appwrite Databases by using an order query. +You can order results returned by Appwrite DocumentsDB by using an order query. For best performance, create an [index](/docs/products/databases/documentsdb/collections#indexes) on the field you plan to order by. # Ordering one field {% #one-field %} diff --git a/src/routes/docs/products/databases/documentsdb/pagination/+page.markdoc b/src/routes/docs/products/databases/documentsdb/pagination/+page.markdoc index 1f310e8ffeb..918642e682f 100644 --- a/src/routes/docs/products/databases/documentsdb/pagination/+page.markdoc +++ b/src/routes/docs/products/databases/documentsdb/pagination/+page.markdoc @@ -1,7 +1,7 @@ --- layout: article title: Pagination -description: Implement pagination for large data sets in Appwrite Databases. Explore techniques for splitting and displaying data across multiple pages. +description: Implement pagination for large data sets in Appwrite DocumentsDB. Explore techniques for splitting and displaying data across multiple pages. --- As your collection grows in size, you'll need to paginate the documents returned. From 99deb376576805642444340a7d5f30c0830ea772 Mon Sep 17 00:00:00 2001 From: Atharva Deosthale <atharva.deosthale17@gmail.com> Date: Thu, 9 Jul 2026 00:54:15 +0530 Subject: [PATCH 6/8] Add PostgreSQL native database docs with integrations --- .optimize-cache.json | 28 + src/lib/utils/code.ts | 9 +- .../databases/postgresql/+layout.svelte | 129 +- .../databases/postgresql/+page.markdoc | 103 +- .../postgresql/backups/+page.markdoc | 1299 +++++++++++++++++ .../postgresql/branches/+page.markdoc | 677 +++++++++ .../connection-pooling/+page.markdoc | 276 ++++ .../postgresql/connections/+page.markdoc | 541 +++++++ .../postgresql/extensions/+page.markdoc | 630 ++++++++ .../high-availability/+page.markdoc | 638 ++++++++ .../integrations/auth-js/+page.markdoc | 229 +++ .../integrations/better-auth/+page.markdoc | 147 ++ .../postgresql/integrations/dbt/+page.markdoc | 114 ++ .../integrations/django/+page.markdoc | 145 ++ .../integrations/drivers/+page.markdoc | 197 +++ .../integrations/drizzle/+page.markdoc | 193 +++ .../integrations/ef-core/+page.markdoc | 168 +++ .../integrations/fastapi/+page.markdoc | 189 +++ .../integrations/gorm/+page.markdoc | 168 +++ .../integrations/grafana/+page.markdoc | 105 ++ .../integrations/laravel/+page.markdoc | 204 +++ .../integrations/metabase/+page.markdoc | 80 + .../integrations/nextjs/+page.markdoc | 150 ++ .../integrations/prisma/+page.markdoc | 222 +++ .../integrations/rails/+page.markdoc | 168 +++ .../integrations/retool/+page.markdoc | 95 ++ .../integrations/spring-boot/+page.markdoc | 182 +++ .../postgresql/maintenance/+page.markdoc | 651 +++++++++ .../postgresql/monitoring/+page.markdoc | 235 +++ .../postgresql/network-security/+page.markdoc | 463 ++++++ .../postgresql/quick-start/+page.markdoc | 96 ++ .../postgresql/scaling/+page.markdoc | 658 +++++++++ .../databases/postgresql/connections.avif | Bin 0 -> 33091 bytes .../postgresql/create-database-specs.avif | Bin 0 -> 32500 bytes .../postgresql/create-database-type.avif | Bin 0 -> 38925 bytes .../databases/postgresql/credentials.avif | Bin 0 -> 16596 bytes .../postgresql/dark/connections.avif | Bin 0 -> 36103 bytes .../dark/create-database-specs.avif | Bin 0 -> 34502 bytes .../postgresql/dark/create-database-type.avif | Bin 0 -> 42082 bytes .../postgresql/dark/credentials.avif | Bin 0 -> 16894 bytes .../databases/postgresql/dark/monitor.avif | Bin 0 -> 48949 bytes .../databases/postgresql/dark/roles-tab.avif | Bin 0 -> 28297 bytes .../dark/settings-compute-tier.avif | Bin 0 -> 43887 bytes .../dark/settings-high-availability.avif | Bin 0 -> 42591 bytes .../postgresql/dark/settings-network.avif | Bin 0 -> 32262 bytes .../postgresql/dark/settings-pitr.avif | Bin 0 -> 33959 bytes .../databases/postgresql/dark/settings.avif | Bin 0 -> 34735 bytes .../databases/postgresql/dark/sql-editor.avif | Bin 0 -> 26576 bytes .../databases/postgresql/monitor.avif | Bin 0 -> 44865 bytes .../databases/postgresql/roles-tab.avif | Bin 0 -> 26872 bytes .../postgresql/settings-compute-tier.avif | Bin 0 -> 41167 bytes .../settings-high-availability.avif | Bin 0 -> 38977 bytes .../postgresql/settings-network.avif | Bin 0 -> 30323 bytes .../databases/postgresql/settings-pitr.avif | Bin 0 -> 31699 bytes .../databases/postgresql/settings.avif | Bin 0 -> 32840 bytes .../databases/postgresql/sql-editor.avif | Bin 0 -> 24588 bytes 56 files changed, 9184 insertions(+), 5 deletions(-) create mode 100644 src/routes/docs/products/databases/postgresql/backups/+page.markdoc create mode 100644 src/routes/docs/products/databases/postgresql/branches/+page.markdoc create mode 100644 src/routes/docs/products/databases/postgresql/connection-pooling/+page.markdoc create mode 100644 src/routes/docs/products/databases/postgresql/connections/+page.markdoc create mode 100644 src/routes/docs/products/databases/postgresql/extensions/+page.markdoc create mode 100644 src/routes/docs/products/databases/postgresql/high-availability/+page.markdoc create mode 100644 src/routes/docs/products/databases/postgresql/integrations/auth-js/+page.markdoc create mode 100644 src/routes/docs/products/databases/postgresql/integrations/better-auth/+page.markdoc create mode 100644 src/routes/docs/products/databases/postgresql/integrations/dbt/+page.markdoc create mode 100644 src/routes/docs/products/databases/postgresql/integrations/django/+page.markdoc create mode 100644 src/routes/docs/products/databases/postgresql/integrations/drivers/+page.markdoc create mode 100644 src/routes/docs/products/databases/postgresql/integrations/drizzle/+page.markdoc create mode 100644 src/routes/docs/products/databases/postgresql/integrations/ef-core/+page.markdoc create mode 100644 src/routes/docs/products/databases/postgresql/integrations/fastapi/+page.markdoc create mode 100644 src/routes/docs/products/databases/postgresql/integrations/gorm/+page.markdoc create mode 100644 src/routes/docs/products/databases/postgresql/integrations/grafana/+page.markdoc create mode 100644 src/routes/docs/products/databases/postgresql/integrations/laravel/+page.markdoc create mode 100644 src/routes/docs/products/databases/postgresql/integrations/metabase/+page.markdoc create mode 100644 src/routes/docs/products/databases/postgresql/integrations/nextjs/+page.markdoc create mode 100644 src/routes/docs/products/databases/postgresql/integrations/prisma/+page.markdoc create mode 100644 src/routes/docs/products/databases/postgresql/integrations/rails/+page.markdoc create mode 100644 src/routes/docs/products/databases/postgresql/integrations/retool/+page.markdoc create mode 100644 src/routes/docs/products/databases/postgresql/integrations/spring-boot/+page.markdoc create mode 100644 src/routes/docs/products/databases/postgresql/maintenance/+page.markdoc create mode 100644 src/routes/docs/products/databases/postgresql/monitoring/+page.markdoc create mode 100644 src/routes/docs/products/databases/postgresql/network-security/+page.markdoc create mode 100644 src/routes/docs/products/databases/postgresql/quick-start/+page.markdoc create mode 100644 src/routes/docs/products/databases/postgresql/scaling/+page.markdoc create mode 100644 static/images/docs/products/databases/postgresql/connections.avif create mode 100644 static/images/docs/products/databases/postgresql/create-database-specs.avif create mode 100644 static/images/docs/products/databases/postgresql/create-database-type.avif create mode 100644 static/images/docs/products/databases/postgresql/credentials.avif create mode 100644 static/images/docs/products/databases/postgresql/dark/connections.avif create mode 100644 static/images/docs/products/databases/postgresql/dark/create-database-specs.avif create mode 100644 static/images/docs/products/databases/postgresql/dark/create-database-type.avif create mode 100644 static/images/docs/products/databases/postgresql/dark/credentials.avif create mode 100644 static/images/docs/products/databases/postgresql/dark/monitor.avif create mode 100644 static/images/docs/products/databases/postgresql/dark/roles-tab.avif create mode 100644 static/images/docs/products/databases/postgresql/dark/settings-compute-tier.avif create mode 100644 static/images/docs/products/databases/postgresql/dark/settings-high-availability.avif create mode 100644 static/images/docs/products/databases/postgresql/dark/settings-network.avif create mode 100644 static/images/docs/products/databases/postgresql/dark/settings-pitr.avif create mode 100644 static/images/docs/products/databases/postgresql/dark/settings.avif create mode 100644 static/images/docs/products/databases/postgresql/dark/sql-editor.avif create mode 100644 static/images/docs/products/databases/postgresql/monitor.avif create mode 100644 static/images/docs/products/databases/postgresql/roles-tab.avif create mode 100644 static/images/docs/products/databases/postgresql/settings-compute-tier.avif create mode 100644 static/images/docs/products/databases/postgresql/settings-high-availability.avif create mode 100644 static/images/docs/products/databases/postgresql/settings-network.avif create mode 100644 static/images/docs/products/databases/postgresql/settings-pitr.avif create mode 100644 static/images/docs/products/databases/postgresql/settings.avif create mode 100644 static/images/docs/products/databases/postgresql/sql-editor.avif diff --git a/.optimize-cache.json b/.optimize-cache.json index 1d753d17ce1..5aa7281391a 100644 --- a/.optimize-cache.json +++ b/.optimize-cache.json @@ -1593,6 +1593,34 @@ "static/images/docs/platform/dark/execution-details.png": "c0481ddc206447460f9d317ba8d421615066f67a50bc9ef41a8f71766ecffb14", "static/images/docs/platform/env-variables.png": "16f95151e4f6ee9fb8056f075b9f5027fd91f0c2a28586c5624c3ffe9b7a1ee8", "static/images/docs/platform/execution-details.png": "ece1364b8b00254bbd982421b6eed6d7f519d34c4e80377fcaaa4cb5d5dd3f89", + "static/images/docs/products/databases/mysql/create-database-specs.png": "623282bddd45eb245adb20166fd336089718a91bb7207a4f22b9811e13b96ba7", + "static/images/docs/products/databases/mysql/create-database-type.png": "0ff2c521f3f40f467587954120339572bcac0c6d6f76f0f2e6935e640d7adba3", + "static/images/docs/products/databases/mysql/dark/create-database-specs.png": "41bcda64b5cfac906639e077549c1429ec3701f8af9f49c4d1548e4716a23028", + "static/images/docs/products/databases/mysql/dark/create-database-type.png": "2a212e8322d6475dfdd2a1599021bd94f5fef42414e76ff13d0a59aca431b287", + "static/images/docs/products/databases/postgresql/connections.png": "e3096521fc169b41bed8a01c77afc923d1fd1ef53939940b90c3bbabeb3294b3", + "static/images/docs/products/databases/postgresql/create-database-specs.png": "80c5136b2df7f9636f230cda64efd024e5a0867d283d5d6750b05b1da8514b25", + "static/images/docs/products/databases/postgresql/create-database-type.png": "dbfb5e319e8ff5cdefb2691d0ab8a9a4a97edb94a62e52fedee726b1585f56f7", + "static/images/docs/products/databases/postgresql/credentials.png": "45d224d28771564581ccb4c4ae8d733fa192e3c8121fd4fefd63e28b91b9b764", + "static/images/docs/products/databases/postgresql/dark/connections.png": "c4a9abd58079668afd131627e8625811bc2d9b902a395050720a8cfafabc341f", + "static/images/docs/products/databases/postgresql/dark/create-database-specs.png": "07d067e17932689a9e014262c6315e46dd8bb2edd4e4619bf112dd743eca7936", + "static/images/docs/products/databases/postgresql/dark/create-database-type.png": "de3281805c2193d8f82ec81b53e1031bdcb6bfdfda875832d041e07d8f407579", + "static/images/docs/products/databases/postgresql/dark/credentials.png": "b44c3e27fe3e217ac048f5207ec55cba75a34ffe0a056290899ab62b70536491", + "static/images/docs/products/databases/postgresql/dark/monitor.png": "f8921ca48411bab35403b13894a8cd05216c931c206f86b853a3d236302660ad", + "static/images/docs/products/databases/postgresql/dark/roles-tab.png": "2fa52745b9e2c6e072332aa4050d4995fe10a779af931f01ad22dd280e337b9e", + "static/images/docs/products/databases/postgresql/dark/settings-compute-tier.png": "8efccefed72b6543f5a62ef64990a150425fad02aaecc531c42d51ac900fb210", + "static/images/docs/products/databases/postgresql/dark/settings-high-availability.png": "d8f12ff6c9b1e6ac1911323ec2ad4591e6bbcdc6bc56f0bc96e9344ff9e5aa5c", + "static/images/docs/products/databases/postgresql/dark/settings-network.png": "cd2924cdfa1457338a0f53a5055f62abf13350b722ef4b788693f1d7861e2631", + "static/images/docs/products/databases/postgresql/dark/settings-pitr.png": "773fc9622de3299b5d94c6de1fda0de53233143be5acc032f6eac65f044434ce", + "static/images/docs/products/databases/postgresql/dark/settings.png": "51ecfdd292149a4b010704b2a21d2f0cad00a5bd3aed1f6f88d9efb35be46f09", + "static/images/docs/products/databases/postgresql/dark/sql-editor.png": "128fa75d8518612915df4a4b5de6c096ab05dd7df48bb89414e3330977ea5a17", + "static/images/docs/products/databases/postgresql/monitor.png": "da2160f8c22ae0dba29619672d04adea9e553e07e342931775fb432cd000c69a", + "static/images/docs/products/databases/postgresql/roles-tab.png": "b13d5caaf9a839ee5dabcbcb156fda3594ed38f7c30c4f092d1095bb5a895edb", + "static/images/docs/products/databases/postgresql/settings-compute-tier.png": "a4a7ed1d2ad3fb01ca8adac0497d075fd58cc11e0f53ece7ed2257eca0828fd8", + "static/images/docs/products/databases/postgresql/settings-high-availability.png": "1a84efe9e0132012d009eac1b52a67739fbf471761ff0cce323f7b160f3aff5b", + "static/images/docs/products/databases/postgresql/settings-network.png": "ef685f1b56c80259c944d39033a895bbddf6aa8744964d47677863b9c94f0ceb", + "static/images/docs/products/databases/postgresql/settings-pitr.png": "267a9f4b60667e618f8c6ff09615c19423cfec7e182421fc929339e537d861cf", + "static/images/docs/products/databases/postgresql/settings.png": "ded8f34bcd1b812ea5a9ddcb48a34db8678ae696a9b03ab16c934b29621b395a", + "static/images/docs/products/databases/postgresql/sql-editor.png": "595b73cbd6f712d31b015ac224f6cb606875fe3a98cb7bf3c09ac6cbec25720a", "static/images/docs/quick-starts/add-platform.png": "3b13ba983ea1d2529a1f34a719acef903ec0b58879ed511012280a28ccbde17e", "static/images/docs/quick-starts/create-project.png": "7fdb25def02c5dbdb08cd38c2d03b7b454c930194a900553e3e68d51cb28a1d5", "static/images/docs/quick-starts/dark/add-platform.png": "b12a85b64b136589268831b9cb26a664ec97418ad25a38be5273baab8253aa16", diff --git a/src/lib/utils/code.ts b/src/lib/utils/code.ts index 87503c1066a..41a9a3089a9 100644 --- a/src/lib/utils/code.ts +++ b/src/lib/utils/code.ts @@ -29,6 +29,8 @@ import groovy from 'highlight.js/lib/languages/groovy'; import rust from 'highlight.js/lib/languages/rust'; import ini from 'highlight.js/lib/languages/ini'; import dockerfile from 'highlight.js/lib/languages/dockerfile'; +import sql from 'highlight.js/lib/languages/sql'; +import pgsql from 'highlight.js/lib/languages/pgsql'; import { Platform } from './references'; import { writable } from 'svelte/store'; @@ -71,7 +73,9 @@ const languages = { env: ini, dotenv: ini, dockerfile: dockerfile, - docker: dockerfile + docker: dockerfile, + sql: sql, + pgsql: pgsql } as const satisfies Record<string, LanguageFn>; const platformAliases: Record<string, keyof typeof languages> = { @@ -114,6 +118,9 @@ Object.entries(platformAliases).forEach(([key, value]) => { /** HashiCorp Configuration Language (Terraform); core highlight.js has no HCL grammar */ hljs.registerAliases(['hcl', 'terraform', 'tf'], { languageName: 'ini' }); +/** Prisma schema language; core highlight.js has no Prisma grammar, GraphQL is the closest match */ +hljs.registerAliases(['prisma'], { languageName: 'graphql' }); + export type Language = keyof typeof languages | Platform; type Args = { diff --git a/src/routes/docs/products/databases/postgresql/+layout.svelte b/src/routes/docs/products/databases/postgresql/+layout.svelte index de7adff91d5..1ae57a78eb2 100644 --- a/src/routes/docs/products/databases/postgresql/+layout.svelte +++ b/src/routes/docs/products/databases/postgresql/+layout.svelte @@ -6,7 +6,7 @@ const parent: NavParent = { href: '/docs/products/databases', - label: 'Databases' + label: 'PostgreSQL' }; const navigation: NavTree = [ @@ -16,6 +16,133 @@ { label: 'Overview', href: '/docs/products/databases/postgresql' + }, + { + label: 'Quick start', + href: '/docs/products/databases/postgresql/quick-start' + } + ] + }, + { + label: 'Connecting', + items: [ + { + label: 'Connections', + href: '/docs/products/databases/postgresql/connections' + }, + { + label: 'Connection pooling', + href: '/docs/products/databases/postgresql/connection-pooling' + } + ] + }, + { + label: 'Manage', + items: [ + { + label: 'Extensions', + href: '/docs/products/databases/postgresql/extensions' + }, + { + label: 'Backups', + href: '/docs/products/databases/postgresql/backups' + }, + { + label: 'Branches', + href: '/docs/products/databases/postgresql/branches' + }, + { + label: 'High availability', + href: '/docs/products/databases/postgresql/high-availability' + }, + { + label: 'Scaling', + href: '/docs/products/databases/postgresql/scaling' + }, + { + label: 'Network security', + href: '/docs/products/databases/postgresql/network-security' + }, + { + label: 'Monitoring', + href: '/docs/products/databases/postgresql/monitoring' + }, + { + label: 'Maintenance', + href: '/docs/products/databases/postgresql/maintenance' + } + ] + }, + { + label: 'Integrations', + items: [ + { + label: 'Node.js drivers', + href: '/docs/products/databases/postgresql/integrations/drivers' + }, + { + label: 'Prisma', + href: '/docs/products/databases/postgresql/integrations/prisma' + }, + { + label: 'Drizzle', + href: '/docs/products/databases/postgresql/integrations/drizzle' + }, + { + label: 'Auth.js', + href: '/docs/products/databases/postgresql/integrations/auth-js' + }, + { + label: 'Better Auth', + href: '/docs/products/databases/postgresql/integrations/better-auth' + }, + { + label: 'Laravel', + href: '/docs/products/databases/postgresql/integrations/laravel' + }, + { + label: 'Rails', + href: '/docs/products/databases/postgresql/integrations/rails' + }, + { + label: 'Django', + href: '/docs/products/databases/postgresql/integrations/django' + }, + { + label: 'FastAPI', + href: '/docs/products/databases/postgresql/integrations/fastapi' + }, + { + label: 'Spring Boot', + href: '/docs/products/databases/postgresql/integrations/spring-boot' + }, + { + label: 'EF Core', + href: '/docs/products/databases/postgresql/integrations/ef-core' + }, + { + label: 'GORM', + href: '/docs/products/databases/postgresql/integrations/gorm' + }, + { + label: 'Next.js', + href: '/docs/products/databases/postgresql/integrations/nextjs' + }, + { + label: 'dbt', + href: '/docs/products/databases/postgresql/integrations/dbt' + }, + { + label: 'Metabase', + href: '/docs/products/databases/postgresql/integrations/metabase' + }, + { + label: 'Grafana', + href: '/docs/products/databases/postgresql/integrations/grafana' + }, + { + label: 'Retool', + href: '/docs/products/databases/postgresql/integrations/retool' } ] } diff --git a/src/routes/docs/products/databases/postgresql/+page.markdoc b/src/routes/docs/products/databases/postgresql/+page.markdoc index 4e7c251d8da..1b4f62973a1 100644 --- a/src/routes/docs/products/databases/postgresql/+page.markdoc +++ b/src/routes/docs/products/databases/postgresql/+page.markdoc @@ -4,8 +4,105 @@ title: PostgreSQL description: Run a dedicated, native PostgreSQL database provisioned for your project and connect to it directly with standard PostgreSQL clients. --- -Run a dedicated, native PostgreSQL database provisioned for your project. Connect to it directly with standard PostgreSQL clients and tools, with no Appwrite abstraction layer in between. Native databases are available on dedicated infrastructure. +Appwrite native PostgreSQL databases give you a managed PostgreSQL instance provisioned for your project. You pick the compute specification, and Appwrite provisions the engine in your project's region with its own storage, networking, and credentials, exposed through a per-database public hostname secured with TLS. -{% info title="Documentation in progress" %} -Detailed PostgreSQL setup and connection guides are on the way. +Native databases are different from Appwrite databases like [TablesDB](/docs/products/databases/tablesdb), [DocumentsDB](/docs/products/databases/documentsdb), and [VectorsDB](/docs/products/databases/vectorsdb), which are accessed through Appwrite SDKs and platform APIs. A native PostgreSQL database gives you the raw engine. You connect with `psql` or any PostgreSQL driver and use the full feature set of PostgreSQL, with no Appwrite abstraction layer in between. + +{% info title="Looking for Appwrite data APIs?" %} +If you want Appwrite SDKs, platform permissions, and serverless scaling for app data, start with [Appwrite Databases](/docs/products/databases). Native PostgreSQL is for teams who want a managed PostgreSQL engine they can talk to directly with their own ORM, migrations, and drivers. {% /info %} + +# Supported versions {% #versions %} + +Appwrite manages the database container, storage, backups, and networking. You bring the application. + +| Engine | Default version | Other supported versions | Default port | +|------------|-----------------|--------------------------|--------------| +| PostgreSQL | 18 | 17 | 5432 | + +The version is selected on create and can be upgraded later. Upgrades run online: a second instance is provisioned on the new version, data is streamed over with logical replication, and traffic cuts over once replication is caught up, with no read or write outages and no manual dump-and-restore. + +A new database starts in a `provisioning` state and becomes `ready` within a few minutes. Large specifications or high-availability configurations take longer to schedule; poll the database status or watch the Console until it reports `ready`. + +# Regions {% #regions %} + +A native database lives in the same region as the project that owns it. There is no per-database region selector. Each database gets a unique hostname in the form `db-<hash>.<region>.appwrite.center`, and data does not leave the region. + +# Feature overview {% #features %} + +{% cards %} +{% cards_item href="/docs/products/databases/postgresql/connections" title="Connections" %} +Connect with `psql` or any driver. Credentials are rotatable from the Console and API. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/connection-pooling" title="Connection pooling" %} +Per-database connection pooler with automatic read/write split when high availability is enabled. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/extensions" title="Extensions" %} +Install PostgreSQL extensions like PostGIS, pgvector, and pg_trgm. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/backups" title="Backups" %} +Scheduled backups, manual backups, restores, and point-in-time recovery. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/branches" title="Branches" %} +Spin up an ephemeral copy of your database in seconds from a storage snapshot. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/high-availability" title="High availability" %} +Up to five synchronous, semi-synchronous, or asynchronous replicas with automatic failover. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/scaling" title="Scaling" %} +Resize compute online and grow storage automatically as your data grows. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/network-security" title="Network security" %} +TLS by default, optional IP allowlists, and a dedicated hostname per database. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/monitoring" title="Monitoring" %} +Live compute, connection, storage, and workload metrics, with an active-connections inspector. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/maintenance" title="Maintenance" %} +Maintenance windows, online version upgrades, and pause and resume. +{% /cards_item %} +{% /cards %} + +# Specifications and pricing {% #specifications %} + +Each database runs against one of the following compute specifications, billed monthly: + +| Tier | Specification | CPU | Memory | Storage | Bandwidth | Connections | Price | +|-----------------|----------------|---------|--------|---------|-----------|-------------|---------| +| Starter | `s-1vcpu-1gb` | 1 core | 1 GB | 10 GB | 50 GB | 100 | $10/mo | +| Standard | `s-2vcpu-2gb` | 2 cores | 2 GB | 25 GB | 200 GB | 200 | $20/mo | +| Standard Plus | `s-2vcpu-4gb` | 2 cores | 4 GB | 50 GB | 400 GB | 500 | $49/mo | +| Professional | `s-4vcpu-8gb` | 4 cores | 8 GB | 200 GB | 1 TB | 1,000 | $85/mo | +| Business | `s-4vcpu-16gb` | 4 cores | 16 GB | 500 GB | 2 TB | 2,000 | $160/mo | +| Business Plus | `s-4vcpu-32gb` | 4 cores | 32 GB | 1 TB | 5 TB | 4,000 | $299/mo | +| Enterprise | `s-8vcpu-32gb` | 8 cores | 32 GB | 2 TB | 7.5 TB | 5,000 | $425/mo | +| Enterprise Plus | `s-8vcpu-64gb` | 8 cores | 64 GB | 3 TB | 10 TB | 10,000 | $699/mo | + +The Storage and Bandwidth columns are the monthly allowances included with each tier. Usage beyond them is billed as overage, and optional features are billed as add-ons on top of the tier price: + +| Add-on | Price | +|----------------------------|---------------------------------| +| Storage overage | $0.125 per GB per month | +| Bandwidth overage | $0.08 per GB per month | +| High availability replica | 50% of the tier price, per replica | +| Point-in-time recovery | 20% of the tier price | + +You can [resize between tiers](/docs/products/databases/postgresql/scaling) at any time with zero downtime. + +# Limits {% #limits %} + +The following limits apply per database: + +| Limit | Value | +|--------------------------------|-----------------------------------------------------------| +| Databases per project | 10 | +| High availability replicas | 0 - 5 | +| IP allowlist entries | 100 | +| Backup retention | 1 - 365 days | +| Point-in-time recovery window | 1 - 35 days | +| Extensions installed | 50 | +| Max simultaneous connections | 10,000 platform cap, lower on smaller specifications | + +# Billing and plan requirements {% #plans %} + +Native databases are available on paid plans, and a payment method must be attached to your organization. Each database is billed by the hour against its [compute specification](#specifications), with separate line items for overages and add-ons. See [pricing](/pricing) for details. diff --git a/src/routes/docs/products/databases/postgresql/backups/+page.markdoc b/src/routes/docs/products/databases/postgresql/backups/+page.markdoc new file mode 100644 index 00000000000..22e538a2714 --- /dev/null +++ b/src/routes/docs/products/databases/postgresql/backups/+page.markdoc @@ -0,0 +1,1299 @@ +--- +layout: article +title: Backups +description: Scheduled backups, manual backups, restores, and point-in-time recovery for your PostgreSQL database. +--- + +Native databases are backed up automatically. Backups are stored off the database instance and restorable from the API. For finer recovery granularity than scheduled backups, enable point-in-time recovery. + +# Automatic backups {% #automatic %} + +Every database gets a default backup policy when it is provisioned, so you have scheduled backups from day one. You can adjust the default policy, or add more policies with different schedules and retention windows. + +# Backup policies {% #policies %} + +A policy defines a schedule (cron expression) and a retention period in days. Create one with: + +{% multicode %} +```server-nodejs +import { Client, Postgresql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +await postgresql.createBackupPolicy({ + databaseId: '<DATABASE_ID>', + policyId: 'hourly', + name: 'Hourly', + schedule: '0 * * * *', + retention: 30, +}); +``` +```server-deno +import { Client, Postgresql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +await postgresql.createBackupPolicy({ + databaseId: '<DATABASE_ID>', + policyId: 'hourly', + name: 'Hourly', + schedule: '0 * * * *', + retention: 30, +}); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Postgresql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$postgresql = new Postgresql($client); + +$postgresql->createBackupPolicy( + databaseId: '<DATABASE_ID>', + policyId: 'hourly', + name: 'Hourly', + schedule: '0 * * * *', + retention: 30, +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.postgresql import Postgresql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +postgresql = Postgresql(client) + +postgresql.create_backup_policy( + database_id='<DATABASE_ID>', + policy_id='hourly', + name='Hourly', + schedule='0 * * * *', + retention=30, +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +postgresql = Postgresql.new(client) + +postgresql.create_backup_policy( + database_id: '<DATABASE_ID>', + policy_id: 'hourly', + name: 'Hourly', + schedule: '0 * * * *', + retention: 30, +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Postgresql postgresql = new Postgresql(client); + +await postgresql.CreateBackupPolicy( + databaseId: "<DATABASE_ID>", + policyId: "hourly", + name: "Hourly", + schedule: "0 * * * *", + retention: 30 +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Postgresql postgresql = Postgresql(client); + +await postgresql.createBackupPolicy( + databaseId: '<DATABASE_ID>', + policyId: 'hourly', + name: 'Hourly', + schedule: '0 * * * *', + retention: 30, +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Postgresql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val postgresql = Postgresql(client) + +postgresql.createBackupPolicy( + databaseId = "<DATABASE_ID>", + policyId = "hourly", + name = "Hourly", + schedule = "0 * * * *", + retention = 30, +) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let postgresql = Postgresql(client) + +_ = try await postgresql.createBackupPolicy( + databaseId: "<DATABASE_ID>", + policyId: "hourly", + name: "Hourly", + schedule: "0 * * * *", + retention: 30 +) +``` +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewPostgresql(client) + + _, err := service.CreateBackupPolicy("<DATABASE_ID>", "hourly", "Hourly", "0 * * * *", 30) + if err != nil { + panic(err) + } +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::postgresql::Postgresql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let postgresql = Postgresql::new(&client); + + postgresql.create_backup_policy("<DATABASE_ID>", "hourly", "Hourly", "0 * * * *", "<ETENTION>", None, None).await?; + + Ok(()) +} +``` +```bash +curl -X POST \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <API_KEY>" \ + -H "Content-Type: application/json" \ + -d '{ + "policyId": "hourly", + "name": "Hourly", + "schedule": "0 * * * *", + "retention": 30 + }' \ + https://<REGION>.cloud.appwrite.io/v1/postgresql/<DATABASE_ID>/backups/policies +``` +{% /multicode %} + +| Parameter | Value | Description | +|-------------|-------------------------------------|-----------------------------------------------| +| `policyId` | custom ID or `unique()` | Policy identifier | +| `name` | text | Display name | +| `schedule` | cron expression | When backups run, for example `0 3 * * *` | +| `retention` | 1 - 365 days | How long backups from this policy are kept | + +List, update, and delete policies with `listBackupPolicies`, `updateBackupPolicy`, and `deleteBackupPolicy`. The number of policies you can create depends on your plan. + +# Manual backups {% #manual %} + +Take an on-demand backup before a risky change: + +{% multicode %} +```server-nodejs +import { Client, Postgresql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +const backup = await postgresql.createBackup({ + databaseId: '<DATABASE_ID>', +}); +``` +```server-deno +import { Client, Postgresql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +const backup = await postgresql.createBackup({ + databaseId: '<DATABASE_ID>', +}); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Postgresql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$postgresql = new Postgresql($client); + +$backup = $postgresql->createBackup( + databaseId: '<DATABASE_ID>', +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.postgresql import Postgresql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +postgresql = Postgresql(client) + +backup = postgresql.create_backup( + database_id='<DATABASE_ID>', +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +postgresql = Postgresql.new(client) + +backup = postgresql.create_backup( + database_id: '<DATABASE_ID>', +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Postgresql postgresql = new Postgresql(client); + +var backup = await postgresql.CreateBackup( + databaseId: "<DATABASE_ID>" +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Postgresql postgresql = Postgresql(client); + +final backup = await postgresql.createBackup( + databaseId: '<DATABASE_ID>', +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Postgresql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val postgresql = Postgresql(client) + +val backup = postgresql.createBackup( + databaseId = "<DATABASE_ID>", +) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let postgresql = Postgresql(client) + +let backup = try await postgresql.createBackup( + databaseId: "<DATABASE_ID>" +) +``` +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewPostgresql(client) + + result, err := service.CreateBackup("<DATABASE_ID>") + if err != nil { + panic(err) + } + _ = result +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::postgresql::Postgresql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let postgresql = Postgresql::new(&client); + + let backup = postgresql.create_backup("<DATABASE_ID>", None).await?; + + Ok(()) +} +``` +```bash +curl -X POST \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <API_KEY>" \ + https://<REGION>.cloud.appwrite.io/v1/postgresql/<DATABASE_ID>/backups +``` +{% /multicode %} + +The backup runs asynchronously with status `pending` until it completes. List backups and check their status with `listBackups`, or fetch one with `getBackup`. + +# Restore from a backup {% #restore %} + +Restoring replaces the database's current data with the backup's contents. The database status moves to `restoring` and returns to `ready` when the restore completes; connections are unavailable during the restore. + +{% multicode %} +```server-nodejs +import { Client, Postgresql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +await postgresql.createRestoration({ + databaseId: '<DATABASE_ID>', + type: 'backup', + backupId: '<BACKUP_ID>', +}); +``` +```server-deno +import { Client, Postgresql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +await postgresql.createRestoration({ + databaseId: '<DATABASE_ID>', + type: 'backup', + backupId: '<BACKUP_ID>', +}); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Postgresql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$postgresql = new Postgresql($client); + +$postgresql->createRestoration( + databaseId: '<DATABASE_ID>', + type: 'backup', + backupId: '<BACKUP_ID>', +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.postgresql import Postgresql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +postgresql = Postgresql(client) + +postgresql.create_restoration( + database_id='<DATABASE_ID>', + type='backup', + backup_id='<BACKUP_ID>', +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +postgresql = Postgresql.new(client) + +postgresql.create_restoration( + database_id: '<DATABASE_ID>', + type: 'backup', + backup_id: '<BACKUP_ID>', +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Postgresql postgresql = new Postgresql(client); + +await postgresql.CreateRestoration( + databaseId: "<DATABASE_ID>", + type: "backup", + backupId: "<BACKUP_ID>" +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Postgresql postgresql = Postgresql(client); + +await postgresql.createRestoration( + databaseId: '<DATABASE_ID>', + type: 'backup', + backupId: '<BACKUP_ID>', +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Postgresql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val postgresql = Postgresql(client) + +postgresql.createRestoration( + databaseId = "<DATABASE_ID>", + type = "backup", + backupId = "<BACKUP_ID>", +) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let postgresql = Postgresql(client) + +_ = try await postgresql.createRestoration( + databaseId: "<DATABASE_ID>", + type: "backup", + backupId: "<BACKUP_ID>" +) +``` +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" + "github.com/appwrite/sdk-for-go/postgresql" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewPostgresql(client) + + _, err := service.CreateRestoration( + "<DATABASE_ID>", + postgresql.WithCreateRestorationType("backup"), + postgresql.WithCreateRestorationBackupId("<BACKUP_ID>"), + ) + if err != nil { + panic(err) + } +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::postgresql::Postgresql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let postgresql = Postgresql::new(&client); + + postgresql.create_restoration("<DATABASE_ID>", Some("backup"), Some("<BACKUP_ID>"), None).await?; + + Ok(()) +} +``` +```bash +curl -X POST \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <API_KEY>" \ + -H "Content-Type: application/json" \ + -d '{ + "type": "backup" + }' \ + https://<REGION>.cloud.appwrite.io/v1/postgresql/<DATABASE_ID>/restorations +``` +{% /multicode %} + +Track progress with `getRestoration` or the database status. + +{% info title="Restores overwrite current data" %} +Everything written after the backup was taken is lost when you restore it. If you need the current state too, take a manual backup first, or use a [branch](/docs/products/databases/postgresql/branches) to inspect data without touching the live database. +{% /info %} + +# Point-in-time recovery {% #pitr %} + +{% only_dark %} +![Point-in-time recovery settings](/images/docs/products/databases/postgresql/dark/settings-pitr.avif) +{% /only_dark %} +{% only_light %} +![Point-in-time recovery settings](/images/docs/products/databases/postgresql/settings-pitr.avif) +{% /only_light %} + +Scheduled backups recover to fixed snapshots. Point-in-time recovery (PITR) continuously archives the write-ahead log, so you can restore to any moment inside the retention window, for example the second before a bad migration ran. + +Enable PITR when creating the database, from **Settings** > **PITR** in the Console, or through the API: + +{% multicode %} +```server-nodejs +import { Client, Postgresql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +await postgresql.update({ + databaseId: '<DATABASE_ID>', + pitr: true, + pitrRetentionDays: 7, +}); +``` +```server-deno +import { Client, Postgresql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +await postgresql.update({ + databaseId: '<DATABASE_ID>', + pitr: true, + pitrRetentionDays: 7, +}); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Postgresql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$postgresql = new Postgresql($client); + +$postgresql->update( + databaseId: '<DATABASE_ID>', + pitr: true, + pitrRetentionDays: 7, +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.postgresql import Postgresql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +postgresql = Postgresql(client) + +postgresql.update( + database_id='<DATABASE_ID>', + pitr=True, + pitr_retention_days=7, +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +postgresql = Postgresql.new(client) + +postgresql.update( + database_id: '<DATABASE_ID>', + pitr: true, + pitr_retention_days: 7, +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Postgresql postgresql = new Postgresql(client); + +await postgresql.Update( + databaseId: "<DATABASE_ID>", + pitr: true, + pitrRetentionDays: 7 +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Postgresql postgresql = Postgresql(client); + +await postgresql.update( + databaseId: '<DATABASE_ID>', + pitr: true, + pitrRetentionDays: 7, +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Postgresql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val postgresql = Postgresql(client) + +postgresql.update( + databaseId = "<DATABASE_ID>", + pitr = true, + pitrRetentionDays = 7, +) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let postgresql = Postgresql(client) + +_ = try await postgresql.update( + databaseId: "<DATABASE_ID>", + pitr: true, + pitrRetentionDays: 7 +) +``` +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" + "github.com/appwrite/sdk-for-go/postgresql" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewPostgresql(client) + + _, err := service.Update( + "<DATABASE_ID>", + postgresql.WithUpdatePitr(true), + postgresql.WithUpdatePitrRetentionDays(7), + ) + if err != nil { + panic(err) + } +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::postgresql::Postgresql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let postgresql = Postgresql::new(&client); + + postgresql.update("<DATABASE_ID>", None, None, None, None, None, None, None, None, Some(true), Some(7), None, None, None, None, None, None, None, None, None, None).await?; + + Ok(()) +} +``` +```bash +curl -X PATCH \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <API_KEY>" \ + -H "Content-Type: application/json" \ + -d '{ + "pitr": true, + "pitrRetentionDays": 7 + }' \ + https://<REGION>.cloud.appwrite.io/v1/postgresql/<DATABASE_ID> +``` +{% /multicode %} + +`pitrRetentionDays` accepts 1 to 35 days. PITR is billed as an add-on on top of your specification; see [pricing](/pricing). + +## Check the recovery window {% #pitr-windows %} + +You can retrieve the time ranges you can restore to. Right after enabling PITR, no recovery window is available yet; the window opens once continuous archiving has captured its first segment. + +{% multicode %} +```server-nodejs +import { Client, Postgresql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +const windows = await postgresql.getPitr({ + databaseId: '<DATABASE_ID>', +}); +``` +```server-deno +import { Client, Postgresql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +const windows = await postgresql.getPitr({ + databaseId: '<DATABASE_ID>', +}); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Postgresql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$postgresql = new Postgresql($client); + +$windows = $postgresql->getPitr( + databaseId: '<DATABASE_ID>', +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.postgresql import Postgresql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +postgresql = Postgresql(client) + +windows = postgresql.get_pitr( + database_id='<DATABASE_ID>', +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +postgresql = Postgresql.new(client) + +windows = postgresql.get_pitr( + database_id: '<DATABASE_ID>', +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Postgresql postgresql = new Postgresql(client); + +var windows = await postgresql.GetPitr( + databaseId: "<DATABASE_ID>" +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Postgresql postgresql = Postgresql(client); + +final windows = await postgresql.getPitr( + databaseId: '<DATABASE_ID>', +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Postgresql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val postgresql = Postgresql(client) + +val windows = postgresql.getPitr( + databaseId = "<DATABASE_ID>", +) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let postgresql = Postgresql(client) + +let windows = try await postgresql.getPitr( + databaseId: "<DATABASE_ID>" +) +``` +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewPostgresql(client) + + result, err := service.GetPitr("<DATABASE_ID>") + if err != nil { + panic(err) + } + _ = result +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::postgresql::Postgresql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let postgresql = Postgresql::new(&client); + + let windows = postgresql.get_pitr("<DATABASE_ID>").await?; + + Ok(()) +} +``` +```bash +curl -X GET \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <API_KEY>" \ + https://<REGION>.cloud.appwrite.io/v1/postgresql/<DATABASE_ID>/pitr +``` +{% /multicode %} + +## Restore to a point in time {% #pitr-restore %} + +Pass a Unix timestamp inside the recovery window: + +{% multicode %} +```server-nodejs +import { Client, Postgresql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +await postgresql.createRestoration({ + databaseId: '<DATABASE_ID>', + type: 'pitr', + targetTime: 1767225600, +}); +``` +```server-deno +import { Client, Postgresql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +await postgresql.createRestoration({ + databaseId: '<DATABASE_ID>', + type: 'pitr', + targetTime: 1767225600, +}); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Postgresql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$postgresql = new Postgresql($client); + +$postgresql->createRestoration( + databaseId: '<DATABASE_ID>', + type: 'pitr', + targetTime: 1767225600, +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.postgresql import Postgresql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +postgresql = Postgresql(client) + +postgresql.create_restoration( + database_id='<DATABASE_ID>', + type='pitr', + target_time=1767225600, +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +postgresql = Postgresql.new(client) + +postgresql.create_restoration( + database_id: '<DATABASE_ID>', + type: 'pitr', + target_time: 1767225600, +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Postgresql postgresql = new Postgresql(client); + +await postgresql.CreateRestoration( + databaseId: "<DATABASE_ID>", + type: "pitr", + targetTime: 1767225600 +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Postgresql postgresql = Postgresql(client); + +await postgresql.createRestoration( + databaseId: '<DATABASE_ID>', + type: 'pitr', + targetTime: 1767225600, +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Postgresql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val postgresql = Postgresql(client) + +postgresql.createRestoration( + databaseId = "<DATABASE_ID>", + type = "pitr", + targetTime = 1767225600, +) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let postgresql = Postgresql(client) + +_ = try await postgresql.createRestoration( + databaseId: "<DATABASE_ID>", + type: "pitr", + targetTime: 1767225600 +) +``` +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" + "github.com/appwrite/sdk-for-go/postgresql" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewPostgresql(client) + + _, err := service.CreateRestoration( + "<DATABASE_ID>", + postgresql.WithCreateRestorationType("pitr"), + postgresql.WithCreateRestorationTargetTime(1767225600), + ) + if err != nil { + panic(err) + } +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::postgresql::Postgresql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let postgresql = Postgresql::new(&client); + + postgresql.create_restoration("<DATABASE_ID>", Some("pitr"), None, Some(1767225600)).await?; + + Ok(()) +} +``` +```bash +curl -X POST \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <API_KEY>" \ + -H "Content-Type: application/json" \ + -d '{ + "type": "pitr", + "targetTime": 1767225600 + }' \ + https://<REGION>.cloud.appwrite.io/v1/postgresql/<DATABASE_ID>/restorations +``` +{% /multicode %} + +Like a backup restore, a PITR restore is in-place: the database is unavailable while restoring and everything after the target time is discarded. + +# Limits {% #limits %} + +| Limit | Value | +|------------------|-----------------| +| Backup retention | 1 - 365 days | +| PITR retention | 1 - 35 days | +| Backup policies | Plan-dependent | diff --git a/src/routes/docs/products/databases/postgresql/branches/+page.markdoc b/src/routes/docs/products/databases/postgresql/branches/+page.markdoc new file mode 100644 index 00000000000..dd3f350d489 --- /dev/null +++ b/src/routes/docs/products/databases/postgresql/branches/+page.markdoc @@ -0,0 +1,677 @@ +--- +layout: article +title: Branches +description: Spin up an ephemeral, isolated copy of your PostgreSQL database in seconds from a storage snapshot. Use branches for previews, migrations, and testing. +--- + +A branch is a short-lived, isolated copy of your database. It has its own endpoint and reuses the parent's credentials, because it is a snapshot copy of the parent's storage volume taken at a point in time. Branches are not replicas: once created, they diverge from the parent and never sync back. + +{% info title="Branches do not merge back" %} +There is no branch merge operation. Use a branch to validate a migration, data repair, or application change, then intentionally cut application traffic over to the validated database or copy the data you want back with engine-native tools. Appwrite does not reconcile two diverged database histories for you. +{% /info %} + +Use cases: + +- **Preview environments**: one branch per pull request, destroyed when the PR closes +- **Test migrations**: apply a destructive `ALTER` against the branch first, observe the behavior, then run it against the source +- **Reproduce a bug**: branch the database, attach a debugger, throw the branch away when done +- **Heavy analytical queries**: `EXPLAIN ANALYZE` experiments against a branch cannot slow down the primary + +# How it works {% #how %} + +Creating a branch takes a fast `CHECKPOINT` on the parent, snapshots the parent's storage volume with a near-instant copy-on-write operation, and provisions a branch instance from the snapshot on the same engine version with its own isolated storage. Branch compute is fixed and lightweight, enough to validate a change rather than carry production load, and is not configurable. The parent and the branch share storage at the moment of branching; storage cost grows as the two diverge. + +# Create a branch {% #create %} + +{% multicode %} +```server-nodejs +import { Client, Postgresql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +await postgresql.createBranch({ + databaseId: '<DATABASE_ID>', + branchId: 'preview', + ttl: 86400, +}); +``` +```server-deno +import { Client, Postgresql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +await postgresql.createBranch({ + databaseId: '<DATABASE_ID>', + branchId: 'preview', + ttl: 86400, +}); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Postgresql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$postgresql = new Postgresql($client); + +$postgresql->createBranch( + databaseId: '<DATABASE_ID>', + branchId: 'preview', + ttl: 86400, +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.postgresql import Postgresql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +postgresql = Postgresql(client) + +postgresql.create_branch( + database_id='<DATABASE_ID>', + branch_id='preview', + ttl=86400, +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +postgresql = Postgresql.new(client) + +postgresql.create_branch( + database_id: '<DATABASE_ID>', + branch_id: 'preview', + ttl: 86400, +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Postgresql postgresql = new Postgresql(client); + +await postgresql.CreateBranch( + databaseId: "<DATABASE_ID>", + branchId: "preview", + ttl: 86400 +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Postgresql postgresql = Postgresql(client); + +await postgresql.createBranch( + databaseId: '<DATABASE_ID>', + branchId: 'preview', + ttl: 86400, +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Postgresql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val postgresql = Postgresql(client) + +postgresql.createBranch( + databaseId = "<DATABASE_ID>", + branchId = "preview", + ttl = 86400, +) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let postgresql = Postgresql(client) + +_ = try await postgresql.createBranch( + databaseId: "<DATABASE_ID>", + branchId: "preview", + ttl: 86400 +) +``` +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" + "github.com/appwrite/sdk-for-go/postgresql" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewPostgresql(client) + + _, err := service.CreateBranch( + "<DATABASE_ID>", + postgresql.WithCreateBranchBranchId("preview"), + postgresql.WithCreateBranchTtl(86400), + ) + if err != nil { + panic(err) + } +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::postgresql::Postgresql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let postgresql = Postgresql::new(&client); + + postgresql.create_branch("<DATABASE_ID>", Some("preview"), Some(86400)).await?; + + Ok(()) +} +``` +```bash +curl -X POST \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <API_KEY>" \ + -H "Content-Type: application/json" \ + -d '{ + "branchId": "preview", + "ttl": 86400 + }' \ + https://<REGION>.cloud.appwrite.io/v1/postgresql/<DATABASE_ID>/branches +``` +{% /multicode %} + +Both fields are optional: + +| Field | Default | Purpose | +|------------|--------------------|-----------------------------------------------------------------------| +| `branchId` | auto-generated | Custom ID (`a-z`, `A-Z`, `0-9`, `.`, `-`, `_`, max 36 chars) | +| `ttl` | `86400` (24 hours) | Lifetime in seconds before the branch expires (min 300, max 604800) | + +The call is asynchronous and returns immediately while the branch provisions in the background. When the TTL elapses, the branch and its storage are removed automatically. + +# List branches and connect {% #list %} + +Each entry carries its metadata and connection details, so there is no separate credentials call: + +{% multicode %} +```server-nodejs +import { Client, Postgresql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +const branches = await postgresql.listBranches({ + databaseId: '<DATABASE_ID>', +}); +``` +```server-deno +import { Client, Postgresql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +const branches = await postgresql.listBranches({ + databaseId: '<DATABASE_ID>', +}); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Postgresql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$postgresql = new Postgresql($client); + +$branches = $postgresql->listBranches( + databaseId: '<DATABASE_ID>', +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.postgresql import Postgresql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +postgresql = Postgresql(client) + +branches = postgresql.list_branches( + database_id='<DATABASE_ID>', +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +postgresql = Postgresql.new(client) + +branches = postgresql.list_branches( + database_id: '<DATABASE_ID>', +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Postgresql postgresql = new Postgresql(client); + +var branches = await postgresql.ListBranches( + databaseId: "<DATABASE_ID>" +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Postgresql postgresql = Postgresql(client); + +final branches = await postgresql.listBranches( + databaseId: '<DATABASE_ID>', +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Postgresql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val postgresql = Postgresql(client) + +val branches = postgresql.listBranches( + databaseId = "<DATABASE_ID>", +) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let postgresql = Postgresql(client) + +let branches = try await postgresql.listBranches( + databaseId: "<DATABASE_ID>" +) +``` +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewPostgresql(client) + + result, err := service.ListBranches("<DATABASE_ID>") + if err != nil { + panic(err) + } + _ = result +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::postgresql::Postgresql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let postgresql = Postgresql::new(&client); + + let branches = postgresql.list_branches("<DATABASE_ID>").await?; + + Ok(()) +} +``` +```bash +curl -X GET \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <API_KEY>" \ + https://<REGION>.cloud.appwrite.io/v1/postgresql/<DATABASE_ID>/branches +``` +{% /multicode %} + +A branch gets its own hostname, and reuses the parent's username and password because it is a snapshot copy of the parent's storage. The port is the standard `5432`; branches have no connection pooler. Connect with the branch's `connectionString` straight from the response: + +```bash +psql "<branch connectionString>" +``` + +# Delete a branch {% #delete %} + +Deleting a branch removes the branch's instance, its storage volume, and the underlying snapshot. There is no soft delete: once the branch is gone, the data is gone. + +{% multicode %} +```server-nodejs +import { Client, Postgresql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +await postgresql.deleteBranch({ + databaseId: '<DATABASE_ID>', + branchId: 'preview', +}); +``` +```server-deno +import { Client, Postgresql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +await postgresql.deleteBranch({ + databaseId: '<DATABASE_ID>', + branchId: 'preview', +}); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Postgresql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$postgresql = new Postgresql($client); + +$postgresql->deleteBranch( + databaseId: '<DATABASE_ID>', + branchId: 'preview', +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.postgresql import Postgresql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +postgresql = Postgresql(client) + +postgresql.delete_branch( + database_id='<DATABASE_ID>', + branch_id='preview', +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +postgresql = Postgresql.new(client) + +postgresql.delete_branch( + database_id: '<DATABASE_ID>', + branch_id: 'preview', +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Postgresql postgresql = new Postgresql(client); + +await postgresql.DeleteBranch( + databaseId: "<DATABASE_ID>", + branchId: "preview" +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Postgresql postgresql = Postgresql(client); + +await postgresql.deleteBranch( + databaseId: '<DATABASE_ID>', + branchId: 'preview', +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Postgresql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val postgresql = Postgresql(client) + +postgresql.deleteBranch( + databaseId = "<DATABASE_ID>", + branchId = "preview", +) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let postgresql = Postgresql(client) + +_ = try await postgresql.deleteBranch( + databaseId: "<DATABASE_ID>", + branchId: "preview" +) +``` +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewPostgresql(client) + + _, err := service.DeleteBranch("<DATABASE_ID>", "preview") + if err != nil { + panic(err) + } +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::postgresql::Postgresql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let postgresql = Postgresql::new(&client); + + postgresql.delete_branch("<DATABASE_ID>", "preview").await?; + + Ok(()) +} +``` +```bash +curl -X DELETE \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <API_KEY>" \ + https://<REGION>.cloud.appwrite.io/v1/postgresql/<DATABASE_ID>/branches/preview +``` +{% /multicode %} + +# Billing {% #billing %} + +A branch runs on fixed, lightweight compute, so its cost is dominated by storage. The snapshot is free at the moment of branching; storage cost accumulates as the branch's data diverges from the parent. There is no separate branch line item, branches roll into your regular database storage and compute totals. + +# Use case: per-PR preview database {% #ci-example %} + +A CI pipeline that branches on every pull request and tears down on close: + +```yaml +name: preview-database + +on: + pull_request: + types: [opened, reopened, closed] + +jobs: + branch: + if: github.event.action != 'closed' + runs-on: ubuntu-latest + steps: + - name: Create branch + run: | + curl -X POST \ + -H "X-Appwrite-Project: ${{ vars.APPWRITE_PROJECT_ID }}" \ + -H "X-Appwrite-Key: ${{ secrets.APPWRITE_API_KEY }}" \ + -H "Content-Type: application/json" \ + -d '{"branchId": "pr-${{ github.event.number }}", "ttl": 604800}' \ + https://<REGION>.cloud.appwrite.io/v1/postgresql/${{ vars.DATABASE_ID }}/branches || true + + teardown: + if: github.event.action == 'closed' + runs-on: ubuntu-latest + steps: + - name: Delete branch + run: | + curl -X DELETE \ + -H "X-Appwrite-Project: ${{ vars.APPWRITE_PROJECT_ID }}" \ + -H "X-Appwrite-Key: ${{ secrets.APPWRITE_API_KEY }}" \ + https://<REGION>.cloud.appwrite.io/v1/postgresql/${{ vars.DATABASE_ID }}/branches/pr-${{ github.event.number }} +``` + +The `|| true` on the create call makes the workflow idempotent: if the branch already exists, the call is a no-op. diff --git a/src/routes/docs/products/databases/postgresql/connection-pooling/+page.markdoc b/src/routes/docs/products/databases/postgresql/connection-pooling/+page.markdoc new file mode 100644 index 00000000000..63fa48e3643 --- /dev/null +++ b/src/routes/docs/products/databases/postgresql/connection-pooling/+page.markdoc @@ -0,0 +1,276 @@ +--- +layout: article +title: Connection pooling +description: Configure the per-database connection pooler to serve many short-lived clients, with automatic read/write splitting when high availability is enabled. +--- + +PostgreSQL creates one backend process per connection, which makes each connection relatively expensive. Serverless functions, edge runtimes, and horizontally scaled application servers can easily exhaust the connection limit of your specification. The connection pooler sits in front of your database and multiplexes many client connections onto a small pool of server connections. + +The pooler runs next to your database and is reachable on port `6432` on the same hostname. Your application connects to the pooler exactly like it would connect to PostgreSQL directly, same credentials, same TLS. The pooler is available on specifications that run on dedicated compute; the smallest specifications run on shared capacity and do not include it. + +# Pool modes {% #modes %} + +| Mode | Behavior | Use for | +|---------------|-----------------------------------------------------------------------------|------------------------------------------------| +| `transaction` | A server connection is assigned for the duration of a transaction, then returned to the pool | Serverless and most applications (default) | +| `session` | A server connection is held for the entire client session | Session-level features: prepared statements, advisory locks, `LISTEN/NOTIFY`, temporary tables | + +Transaction mode gives the highest connection multiplexing but does not support session-level state. If your framework prepares statements at the session level, either switch the driver to unnamed prepared statements or use session mode. + +# Configure the pooler {% #configure %} + +Read the current pooler configuration with `getPooler`, and tune the pool mode and sizes with `updatePooler`. All parameters are optional; omitted values keep their current setting. + +{% multicode %} +```server-nodejs +import { Client, Postgresql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +const pooler = await postgresql.updatePooler({ + databaseId: '<DATABASE_ID>', + mode: 'transaction', + maxConnections: 500, + defaultPoolSize: 25, +}); +``` +```server-deno +import { Client, Postgresql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +const pooler = await postgresql.updatePooler({ + databaseId: '<DATABASE_ID>', + mode: 'transaction', + maxConnections: 500, + defaultPoolSize: 25, +}); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Postgresql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$postgresql = new Postgresql($client); + +$pooler = $postgresql->updatePooler( + databaseId: '<DATABASE_ID>', + mode: 'transaction', + maxConnections: 500, + defaultPoolSize: 25, +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.postgresql import Postgresql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +postgresql = Postgresql(client) + +pooler = postgresql.update_pooler( + database_id='<DATABASE_ID>', + mode='transaction', + max_connections=500, + default_pool_size=25, +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +postgresql = Postgresql.new(client) + +pooler = postgresql.update_pooler( + database_id: '<DATABASE_ID>', + mode: 'transaction', + max_connections: 500, + default_pool_size: 25, +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Postgresql postgresql = new Postgresql(client); + +var pooler = await postgresql.UpdatePooler( + databaseId: "<DATABASE_ID>", + mode: "transaction", + maxConnections: 500, + defaultPoolSize: 25 +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Postgresql postgresql = Postgresql(client); + +final pooler = await postgresql.updatePooler( + databaseId: '<DATABASE_ID>', + mode: 'transaction', + maxConnections: 500, + defaultPoolSize: 25, +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Postgresql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val postgresql = Postgresql(client) + +val pooler = postgresql.updatePooler( + databaseId = "<DATABASE_ID>", + mode = "transaction", + maxConnections = 500, + defaultPoolSize = 25, +) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let postgresql = Postgresql(client) + +let pooler = try await postgresql.updatePooler( + databaseId: "<DATABASE_ID>", + mode: "transaction", + maxConnections: 500, + defaultPoolSize: 25 +) +``` +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" + "github.com/appwrite/sdk-for-go/postgresql" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewPostgresql(client) + + result, err := service.UpdatePooler( + "<DATABASE_ID>", + postgresql.WithUpdatePoolerMode("transaction"), + postgresql.WithUpdatePoolerMaxConnections(500), + postgresql.WithUpdatePoolerDefaultPoolSize(25), + ) + if err != nil { + panic(err) + } + _ = result +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::postgresql::Postgresql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let postgresql = Postgresql::new(&client); + + let pooler = postgresql.update_pooler("<DATABASE_ID>", Some("transaction"), Some(500), Some(25), None, None, None, None, None).await?; + + Ok(()) +} +``` +```bash +curl -X PATCH \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <API_KEY>" \ + -H "Content-Type: application/json" \ + -d '{ + "mode": "transaction", + "maxConnections": 500, + "defaultPoolSize": 25 + }' \ + https://<REGION>.cloud.appwrite.io/v1/postgresql/<DATABASE_ID>/pooler +``` +{% /multicode %} + +| Parameter | Range | Description | +|----------------------|----------------|--------------------------------------------------------------------------------| +| `mode` | `transaction`, `session` | How long a server connection stays assigned to a client | +| `maxConnections` | 10 - 10,000 | Maximum pooled client connections. Cannot exceed the connection cap of your specification | +| `defaultPoolSize` | 1 - 1,000 | Server connections per user in the pool | +| `readWriteSplitting` | boolean | Route `SELECT`s to replicas, writes and locked reads to the primary. Defaults to on when high availability is enabled | + +The same settings are available in the Console under **Settings** > **Connection pooler**. + +# Connect through the pooler {% #connect %} + +Take your normal connection string and change the port to `6432`: + +```bash +postgresql://admin:<password>@db-<hash>.<region>.appwrite.center:6432/<database> +``` + +Point your application's runtime traffic at the pooler port. Keep migrations and long-lived administrative sessions on the direct port `5432`, schema changes and tools like `pg_dump` expect session semantics and can misbehave in transaction mode. + +# Read/write splitting {% #read-write-splitting %} + +When [high availability](/docs/products/databases/postgresql/high-availability) is enabled, the pooler can route read-only statements to replicas and everything else to the primary. `SELECT ... FOR UPDATE` and statements inside explicit transactions go to the primary. Replicas replicate asynchronously by default, so a read that immediately follows a write can be stale; use `sync` or `quorum` replication mode if you need read-your-writes consistency through the pooler. + +# Sizing guidance {% #sizing %} + +A useful starting point for `defaultPoolSize` is `4 x CPU cores` of your specification, and it rarely helps to go above your specification's connection cap divided by the number of databases sharing the workload. Watch the connection metrics in the [Monitor tab](/docs/products/databases/postgresql/monitoring) and increase the pool only when clients queue for a connection. + +# When not to use the pooler {% #when-not %} + +Skip the pooler when you have a small, fixed number of long-lived application servers that each maintain their own driver-level pool, and their combined connection count fits comfortably in your specification's limit. Adding a pooler in that setup only adds a hop. diff --git a/src/routes/docs/products/databases/postgresql/connections/+page.markdoc b/src/routes/docs/products/databases/postgresql/connections/+page.markdoc new file mode 100644 index 00000000000..300a2cc2050 --- /dev/null +++ b/src/routes/docs/products/databases/postgresql/connections/+page.markdoc @@ -0,0 +1,541 @@ +--- +layout: article +title: Connections +description: Connect to your PostgreSQL database with psql or any standard driver. Retrieve connection details and rotate the primary password. +--- + +A native PostgreSQL database exposes a PostgreSQL endpoint over TLS. You connect to it the same way you would connect to any PostgreSQL server: with `psql`, any driver in any language, or any ORM. + +# Get connection details in the Console {% #console %} + +{% only_dark %} +![Database credentials dialog](/images/docs/products/databases/postgresql/dark/credentials.avif) +{% /only_dark %} +{% only_light %} +![Database credentials dialog](/images/docs/products/databases/postgresql/credentials.avif) +{% /only_light %} + +The fastest way to connect is through the Appwrite Console: + +1. In your project, go to **Databases** and select your PostgreSQL database. +2. Click **Credentials** to open the credentials dialog. +3. Copy the individual values from the **Details** tab, or switch to the **DSN**, **.env**, **Prisma**, **Drizzle**, or **psql** tab for a ready-made snippet. +4. Paste it into `psql`, your ORM, or your database client. + +Use the API flow below when you need to fetch connection details from automation or inject them into your deployment pipeline. + +# Get connection details with the API {% #credentials %} + +The connection details are returned on the database object itself. Fetch the database with an API key that has the `databases.read` scope: + +{% multicode %} +```server-nodejs +import { Client, Postgresql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +const database = await postgresql.get({ + databaseId: '<DATABASE_ID>', +}); + +console.log(database.connectionString); +``` +```server-deno +import { Client, Postgresql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +const database = await postgresql.get({ + databaseId: '<DATABASE_ID>', +}); + +console.log(database.connectionString); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Postgresql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$postgresql = new Postgresql($client); + +$database = $postgresql->get(databaseId: '<DATABASE_ID>'); + +echo $database['connectionString']; +``` +```server-python +from appwrite.client import Client +from appwrite.services.postgresql import Postgresql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +postgresql = Postgresql(client) + +database = postgresql.get(database_id='<DATABASE_ID>') + +print(database.connection_string) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +postgresql = Postgresql.new(client) + +database = postgresql.get(database_id: '<DATABASE_ID>') + +puts database.connection_string +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Postgresql postgresql = new Postgresql(client); + +var database = await postgresql.Get(databaseId: "<DATABASE_ID>"); + +Console.WriteLine(database.ConnectionString); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Postgresql postgresql = Postgresql(client); + +final database = await postgresql.get( + databaseId: '<DATABASE_ID>', +); + +print(database.connectionString); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Postgresql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val postgresql = Postgresql(client) + +val database = postgresql.get( + databaseId = "<DATABASE_ID>", +) + +println(database.connectionString) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let postgresql = Postgresql(client) + +let database = try await postgresql.get( + databaseId: "<DATABASE_ID>" +) + +print(database.connectionString) +``` +```server-go +package main + +import ( + "fmt" + + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + postgresql := appwrite.NewPostgresql(client) + + database, err := postgresql.Get("<DATABASE_ID>") + if err != nil { + panic(err) + } + fmt.Println(database.ConnectionString) +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::postgresql::Postgresql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let postgresql = Postgresql::new(&client); + + let database = postgresql.get("<DATABASE_ID>").await?; + + println!("{}", database.connection_string); + + Ok(()) +} +``` +```bash +curl -X GET \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <API_KEY>" \ + https://<REGION>.cloud.appwrite.io/v1/postgresql/<DATABASE_ID> +``` +{% /multicode %} + +The response includes the connection fields alongside the database configuration: + +```json +{ + "$id": "<DATABASE_ID>", + "name": "main", + "engine": "postgresql", + "version": "18", + "status": "ready", + "hostname": "db-<hash>.<region>.appwrite.center", + "connectionPort": 5432, + "connectionUser": "admin", + "connectionPassword": "<password>", + "connectionString": "postgresql://admin:<password>@db-<hash>.<region>.appwrite.center:5432/<database>" +} +``` + +The primary user is `admin` and the database name is generated per database. + +# Connect with psql {% #psql %} + +Pass the connection string, or the individual values, to `psql`. The Console credentials dialog also has a **psql** tab with the command ready to copy. + +```bash +psql "postgresql://admin:<password>@db-<hash>.<region>.appwrite.center:5432/<database>" +``` + +Or with individual flags: + +```bash +psql -h db-<hash>.<region>.appwrite.center -p 5432 -U admin -d <database> +``` + +# Rotate the primary password {% #rotate %} + +If your password is compromised, or your security policy requires regular rotation, you can issue a new password for the primary user. The change is applied atomically in the engine, and the response carries the new connection details. Existing sessions stay alive until they disconnect, then have to authenticate with the new password. The API key needs the `databases.write` scope. + +{% multicode %} +```server-nodejs +import { Client, Postgresql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +const database = await postgresql.updateCredentials({ + databaseId: '<DATABASE_ID>', +}); +``` +```server-deno +import { Client, Postgresql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +const database = await postgresql.updateCredentials({ + databaseId: '<DATABASE_ID>', +}); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Postgresql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$postgresql = new Postgresql($client); + +$database = $postgresql->updateCredentials(databaseId: '<DATABASE_ID>'); +``` +```server-python +from appwrite.client import Client +from appwrite.services.postgresql import Postgresql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +postgresql = Postgresql(client) + +database = postgresql.update_credentials(database_id='<DATABASE_ID>') +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +postgresql = Postgresql.new(client) + +database = postgresql.update_credentials(database_id: '<DATABASE_ID>') +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Postgresql postgresql = new Postgresql(client); + +var database = await postgresql.UpdateCredentials(databaseId: "<DATABASE_ID>"); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Postgresql postgresql = Postgresql(client); + +final database = await postgresql.updateCredentials( + databaseId: '<DATABASE_ID>', +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Postgresql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val postgresql = Postgresql(client) + +val database = postgresql.updateCredentials( + databaseId = "<DATABASE_ID>", +) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let postgresql = Postgresql(client) + +let database = try await postgresql.updateCredentials( + databaseId: "<DATABASE_ID>" +) +``` +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + postgresql := appwrite.NewPostgresql(client) + + _, err := postgresql.UpdateCredentials("<DATABASE_ID>") + if err != nil { + panic(err) + } +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::postgresql::Postgresql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let postgresql = Postgresql::new(&client); + + let database = postgresql.update_credentials("<DATABASE_ID>").await?; + + Ok(()) +} +``` +```bash +curl -X PATCH \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <API_KEY>" \ + https://<REGION>.cloud.appwrite.io/v1/postgresql/<DATABASE_ID>/credentials +``` +{% /multicode %} + +# Database roles {% #roles %} + +{% only_dark %} +![Database roles tab](/images/docs/products/databases/postgresql/dark/roles-tab.avif) +{% /only_dark %} +{% only_light %} +![Database roles tab](/images/docs/products/databases/postgresql/roles-tab.avif) +{% /only_light %} + +The primary `admin` role owns the default database. For applications that need narrower access, such as a read-only reporting user or a write-only ingestion user, create additional PostgreSQL roles from the **Roles** tab of your database in the Console. The list shows each role's login, role-creation, and database-creation privileges, its connection limit, and its role memberships. + +Roles are standard PostgreSQL roles, so `GRANT` and `REVOKE` statements in the [SQL editor](/docs/products/databases/postgresql/quick-start#first-queries) or `psql` work on them like on any PostgreSQL server. The `postgres` superuser is managed by Appwrite and cannot be modified. + +# TLS {% #tls %} + +Connections on Appwrite Cloud are encrypted with TLS, terminated at the edge and forwarded to your database over the internal network. The connection string from the credentials dialog carries the right SSL settings for your environment, so drivers need no extra configuration. + +For IP allowlists and other network controls, see [network security](/docs/products/databases/postgresql/network-security). + +# Connecting from an application {% #drivers %} + +There is nothing Appwrite-specific about the driver setup. A few example snippets: + +{% multicode %} +```server-nodejs +import { Client } from 'pg'; + +const client = new Client({ + connectionString: process.env.DATABASE_URL, +}); + +await client.connect(); +const { rows } = await client.query('SELECT now()'); +console.log(rows); +``` +```server-python +import os +import psycopg + +with psycopg.connect(os.environ['DATABASE_URL']) as conn: + with conn.cursor() as cur: + cur.execute('SELECT now()') + print(cur.fetchone()) +``` +```server-php +<?php + +$pdo = new PDO(getenv('DATABASE_DSN')); + +$rows = $pdo->query('SELECT now()')->fetchAll(); +print_r($rows); +``` +```server-go +package main + +import ( + "context" + "fmt" + "os" + + "github.com/jackc/pgx/v5" +) + +func main() { + conn, err := pgx.Connect(context.Background(), os.Getenv("DATABASE_URL")) + if err != nil { + panic(err) + } + defer conn.Close(context.Background()) + + var now string + if err := conn.QueryRow(context.Background(), "SELECT now()").Scan(&now); err != nil { + panic(err) + } + fmt.Println(now) +} +``` +```server-rust +use tokio_postgres::NoTls; + +#[tokio::main] +async fn main() -> Result<(), tokio_postgres::Error> { + let url = std::env::var("DATABASE_URL").expect("DATABASE_URL"); + let (client, connection) = tokio_postgres::connect(&url, NoTls).await?; + + tokio::spawn(async move { + if let Err(e) = connection.await { + eprintln!("connection error: {e}"); + } + }); + + let row = client.query_one("SELECT now()::text", &[]).await?; + let now: &str = row.get(0); + println!("{now}"); + + Ok(()) +} +``` +{% /multicode %} + +Set `DATABASE_URL` to the connection string from the credentials dialog. Once you can run a query, you can use any tool that talks the PostgreSQL wire protocol: pgAdmin, DataGrip, your ORM of choice, your migration tool of choice. Appwrite gets out of the way. diff --git a/src/routes/docs/products/databases/postgresql/extensions/+page.markdoc b/src/routes/docs/products/databases/postgresql/extensions/+page.markdoc new file mode 100644 index 00000000000..0d9c0e155fa --- /dev/null +++ b/src/routes/docs/products/databases/postgresql/extensions/+page.markdoc @@ -0,0 +1,630 @@ +--- +layout: article +title: Extensions +description: Install and manage PostgreSQL extensions like PostGIS, pgvector, and pg_trgm on your database, at no extra cost. +--- + +PostgreSQL exposes a rich extension ecosystem: PostGIS for geospatial data, pgvector for embeddings, pg_trgm for fuzzy search, and more. Native PostgreSQL databases on Appwrite support managing extensions through the API, at no extra cost. + +# Install an extension {% #install %} + +Pass the extension name as it appears in the [extension catalog](#list). The install runs asynchronously: the request returns immediately and a worker runs `CREATE EXTENSION` inside the database, typically within a few seconds. The database must be in the `ready` state. + +{% multicode %} +```server-nodejs +import { Client, Postgresql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +await postgresql.createExtension({ + databaseId: '<DATABASE_ID>', + name: 'vector', +}); +``` +```server-deno +import { Client, Postgresql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +await postgresql.createExtension({ + databaseId: '<DATABASE_ID>', + name: 'vector', +}); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Postgresql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$postgresql = new Postgresql($client); + +$postgresql->createExtension( + databaseId: '<DATABASE_ID>', + name: 'vector', +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.postgresql import Postgresql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +postgresql = Postgresql(client) + +postgresql.create_extension( + database_id='<DATABASE_ID>', + name='vector', +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +postgresql = Postgresql.new(client) + +postgresql.create_extension( + database_id: '<DATABASE_ID>', + name: 'vector', +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Postgresql postgresql = new Postgresql(client); + +await postgresql.CreateExtension( + databaseId: "<DATABASE_ID>", + name: "vector" +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Postgresql postgresql = Postgresql(client); + +await postgresql.createExtension( + databaseId: '<DATABASE_ID>', + name: 'vector', +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Postgresql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val postgresql = Postgresql(client) + +postgresql.createExtension( + databaseId = "<DATABASE_ID>", + name = "vector", +) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let postgresql = Postgresql(client) + +_ = try await postgresql.createExtension( + databaseId: "<DATABASE_ID>", + name: "vector" +) +``` +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewPostgresql(client) + + _, err := service.CreateExtension("<DATABASE_ID>", "vector") + if err != nil { + panic(err) + } +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::postgresql::Postgresql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let postgresql = Postgresql::new(&client); + + postgresql.create_extension("<DATABASE_ID>", "vector").await?; + + Ok(()) +} +``` +```bash +curl -X POST \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <API_KEY>" \ + -H "Content-Type: application/json" \ + -d '{ + "name": "vector" + }' \ + https://<REGION>.cloud.appwrite.io/v1/postgresql/<DATABASE_ID>/extensions +``` +{% /multicode %} + +Requesting an extension that is not available fails with an error listing the supported extension names. + +# List extensions {% #list %} + +Lists the extensions installed on the database and the extensions available to install: + +{% multicode %} +```server-nodejs +import { Client, Postgresql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +const extensions = await postgresql.listExtensions({ + databaseId: '<DATABASE_ID>', +}); +``` +```server-deno +import { Client, Postgresql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +const extensions = await postgresql.listExtensions({ + databaseId: '<DATABASE_ID>', +}); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Postgresql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$postgresql = new Postgresql($client); + +$extensions = $postgresql->listExtensions( + databaseId: '<DATABASE_ID>', +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.postgresql import Postgresql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +postgresql = Postgresql(client) + +extensions = postgresql.list_extensions( + database_id='<DATABASE_ID>', +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +postgresql = Postgresql.new(client) + +extensions = postgresql.list_extensions( + database_id: '<DATABASE_ID>', +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Postgresql postgresql = new Postgresql(client); + +var extensions = await postgresql.ListExtensions( + databaseId: "<DATABASE_ID>" +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Postgresql postgresql = Postgresql(client); + +final extensions = await postgresql.listExtensions( + databaseId: '<DATABASE_ID>', +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Postgresql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val postgresql = Postgresql(client) + +val extensions = postgresql.listExtensions( + databaseId = "<DATABASE_ID>", +) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let postgresql = Postgresql(client) + +let extensions = try await postgresql.listExtensions( + databaseId: "<DATABASE_ID>" +) +``` +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewPostgresql(client) + + result, err := service.ListExtensions("<DATABASE_ID>") + if err != nil { + panic(err) + } + _ = result +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::postgresql::Postgresql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let postgresql = Postgresql::new(&client); + + let extensions = postgresql.list_extensions("<DATABASE_ID>").await?; + + Ok(()) +} +``` +```bash +curl -X GET \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <API_KEY>" \ + https://<REGION>.cloud.appwrite.io/v1/postgresql/<DATABASE_ID>/extensions +``` +{% /multicode %} + +The response contains two arrays of extension names: + +```json +{ + "installed": ["plpgsql", "vector"], + "available": ["postgis", "pg_trgm", "pgcrypto", "hstore", "citext", "..."] +} +``` + +The available list is reported by the engine for your PostgreSQL version, so it always reflects what can actually be installed on your database. + +# Remove an extension {% #remove %} + +{% multicode %} +```server-nodejs +import { Client, Postgresql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +await postgresql.deleteExtension({ + databaseId: '<DATABASE_ID>', + extensionName: 'vector', +}); +``` +```server-deno +import { Client, Postgresql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +await postgresql.deleteExtension({ + databaseId: '<DATABASE_ID>', + extensionName: 'vector', +}); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Postgresql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$postgresql = new Postgresql($client); + +$postgresql->deleteExtension( + databaseId: '<DATABASE_ID>', + extensionName: 'vector', +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.postgresql import Postgresql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +postgresql = Postgresql(client) + +postgresql.delete_extension( + database_id='<DATABASE_ID>', + extension_name='vector', +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +postgresql = Postgresql.new(client) + +postgresql.delete_extension( + database_id: '<DATABASE_ID>', + extension_name: 'vector', +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Postgresql postgresql = new Postgresql(client); + +await postgresql.DeleteExtension( + databaseId: "<DATABASE_ID>", + extensionName: "vector" +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Postgresql postgresql = Postgresql(client); + +await postgresql.deleteExtension( + databaseId: '<DATABASE_ID>', + extensionName: 'vector', +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Postgresql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val postgresql = Postgresql(client) + +postgresql.deleteExtension( + databaseId = "<DATABASE_ID>", + extensionName = "vector", +) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let postgresql = Postgresql(client) + +_ = try await postgresql.deleteExtension( + databaseId: "<DATABASE_ID>", + extensionName: "vector" +) +``` +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewPostgresql(client) + + _, err := service.DeleteExtension("<DATABASE_ID>", "vector") + if err != nil { + panic(err) + } +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::postgresql::Postgresql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let postgresql = Postgresql::new(&client); + + postgresql.delete_extension("<DATABASE_ID>", "vector").await?; + + Ok(()) +} +``` +```bash +curl -X DELETE \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <API_KEY>" \ + https://<REGION>.cloud.appwrite.io/v1/postgresql/<DATABASE_ID>/extensions/vector +``` +{% /multicode %} + +If there are objects that depend on the extension (tables, indexes, columns), the drop fails. Drop the dependents first, or run `DROP EXTENSION ... CASCADE` yourself through SQL to acknowledge what gets removed. + +# Common extensions {% #common %} + +A few extensions worth knowing about: + +| Name | Use case | +|-------------|-----------------------------------------------------------------------| +| `vector` | Vector data type and similarity search for embeddings (pgvector) | +| `postgis` | Spatial data types, indexes, and functions for geographic objects | +| `pg_trgm` | Trigram matching for fuzzy string search and similarity | +| `pgcrypto` | Cryptographic functions for hashing and encryption | +| `uuid-ossp` | Generate universally unique identifiers (UUIDs) | +| `hstore` | Store sets of key/value pairs within a single column | +| `citext` | Case-insensitive character string data type | +| `ltree` | Represent and query hierarchical tree-like data | + +List the extensions on your database for the full catalog available to it. + +# Limits {% #limits %} + +| Limit | Value | +|---------------------------------|------------| +| Maximum extensions per database | 50 | +| Extension install and uninstall | Free | + +Extensions are installed at their default version for your database's PostgreSQL major version. diff --git a/src/routes/docs/products/databases/postgresql/high-availability/+page.markdoc b/src/routes/docs/products/databases/postgresql/high-availability/+page.markdoc new file mode 100644 index 00000000000..f5036f1f6e4 --- /dev/null +++ b/src/routes/docs/products/databases/postgresql/high-availability/+page.markdoc @@ -0,0 +1,638 @@ +--- +layout: article +title: High availability +description: Run up to five read replicas with asynchronous, synchronous, or quorum replication and automatic failover for your PostgreSQL database. +--- + +A single database instance is a single point of failure. High availability (HA) adds streaming replicas next to your primary: they replicate continuously, serve read traffic through the [connection pooler](/docs/products/databases/postgresql/connection-pooling), and take over automatically when the primary becomes unhealthy. + +High availability requires a specification that runs on dedicated compute; the smallest specifications run on shared capacity and do not support replicas. + +# How it works {% #how-it-works %} + +Replicas receive changes from the primary through PostgreSQL streaming replication (WAL shipping). Each replica is a full copy of the database on its own compute. When the primary fails, the most caught-up replica is promoted to primary and the hostname is repointed, your application keeps connecting to the same host and port. + +# Replication modes {% #sync-modes %} + +| Mode | Behavior | Trade-off | +|----------|----------------------------------------------------------------------------------|--------------------------------------------------| +| `async` | The primary commits without waiting for replicas | Fastest writes; a failover can lose the last moments of writes | +| `sync` | The primary waits for one replica to confirm each commit | No data loss on single failure; slightly higher write latency | +| `quorum` | The primary waits for a majority of replicas to confirm each commit | Strongest durability; highest write latency | + +`async` is the default. For production workloads that cannot lose acknowledged writes, use `sync` with at least two replicas. + +# Enable high availability {% #enable %} + +{% only_dark %} +![High availability settings](/images/docs/products/databases/postgresql/dark/settings-high-availability.avif) +{% /only_dark %} +{% only_light %} +![High availability settings](/images/docs/products/databases/postgresql/settings-high-availability.avif) +{% /only_light %} + +Set the replica count and replication mode on the database, from **Settings** > **High availability** in the Console or through the API: + +{% multicode %} +```server-nodejs +import { Client, Postgresql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +await postgresql.update({ + databaseId: '<DATABASE_ID>', + replicas: 2, + syncMode: 'sync', +}); +``` +```server-deno +import { Client, Postgresql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +await postgresql.update({ + databaseId: '<DATABASE_ID>', + replicas: 2, + syncMode: 'sync', +}); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Postgresql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$postgresql = new Postgresql($client); + +$postgresql->update( + databaseId: '<DATABASE_ID>', + replicas: 2, + syncMode: 'sync', +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.postgresql import Postgresql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +postgresql = Postgresql(client) + +postgresql.update( + database_id='<DATABASE_ID>', + replicas=2, + sync_mode='sync', +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +postgresql = Postgresql.new(client) + +postgresql.update( + database_id: '<DATABASE_ID>', + replicas: 2, + sync_mode: 'sync', +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Postgresql postgresql = new Postgresql(client); + +await postgresql.Update( + databaseId: "<DATABASE_ID>", + replicas: 2, + syncMode: "sync" +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Postgresql postgresql = Postgresql(client); + +await postgresql.update( + databaseId: '<DATABASE_ID>', + replicas: 2, + syncMode: 'sync', +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Postgresql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val postgresql = Postgresql(client) + +postgresql.update( + databaseId = "<DATABASE_ID>", + replicas = 2, + syncMode = "sync", +) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let postgresql = Postgresql(client) + +_ = try await postgresql.update( + databaseId: "<DATABASE_ID>", + replicas: 2, + syncMode: "sync" +) +``` +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" + "github.com/appwrite/sdk-for-go/postgresql" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewPostgresql(client) + + _, err := service.Update( + "<DATABASE_ID>", + postgresql.WithUpdateReplicas(2), + postgresql.WithUpdateSyncMode("sync"), + ) + if err != nil { + panic(err) + } +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::postgresql::Postgresql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let postgresql = Postgresql::new(&client); + + postgresql.update("<DATABASE_ID>", None, None, None, None, Some("sync"), None, None, None, None, None, None, None, None, None, None, None, None, None, None, None).await?; + + Ok(()) +} +``` +```bash +curl -X PATCH \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <API_KEY>" \ + -H "Content-Type: application/json" \ + -d '{ + "replicas": 2, + "syncMode": "sync" + }' \ + https://<REGION>.cloud.appwrite.io/v1/postgresql/<DATABASE_ID> +``` +{% /multicode %} + +Adding replicas provisions them online; the primary keeps serving traffic while each replica seeds from a snapshot and catches up. Setting `replicas` back to `0` disables HA. + +# Check replication status {% #status %} + +You can check each replica's role, health, and replication lag: + +{% multicode %} +```server-nodejs +import { Client, Postgresql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +const replicas = await postgresql.getReplicas({ + databaseId: '<DATABASE_ID>', +}); +``` +```server-deno +import { Client, Postgresql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +const replicas = await postgresql.getReplicas({ + databaseId: '<DATABASE_ID>', +}); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Postgresql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$postgresql = new Postgresql($client); + +$replicas = $postgresql->getReplicas( + databaseId: '<DATABASE_ID>', +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.postgresql import Postgresql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +postgresql = Postgresql(client) + +replicas = postgresql.get_replicas( + database_id='<DATABASE_ID>', +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +postgresql = Postgresql.new(client) + +replicas = postgresql.get_replicas( + database_id: '<DATABASE_ID>', +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Postgresql postgresql = new Postgresql(client); + +var replicas = await postgresql.GetReplicas( + databaseId: "<DATABASE_ID>" +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Postgresql postgresql = Postgresql(client); + +final replicas = await postgresql.getReplicas( + databaseId: '<DATABASE_ID>', +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Postgresql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val postgresql = Postgresql(client) + +val replicas = postgresql.getReplicas( + databaseId = "<DATABASE_ID>", +) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let postgresql = Postgresql(client) + +let replicas = try await postgresql.getReplicas( + databaseId: "<DATABASE_ID>" +) +``` +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewPostgresql(client) + + result, err := service.GetReplicas("<DATABASE_ID>") + if err != nil { + panic(err) + } + _ = result +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::postgresql::Postgresql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let postgresql = Postgresql::new(&client); + + let replicas = postgresql.get_replicas("<DATABASE_ID>").await?; + + Ok(()) +} +``` +```bash +curl -X GET \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <API_KEY>" \ + https://<REGION>.cloud.appwrite.io/v1/postgresql/<DATABASE_ID>/replicas +``` +{% /multicode %} + +# Automatic failover {% #automatic-failover %} + +Appwrite continuously health-checks the primary. When it becomes unresponsive, the platform promotes the replica with the least replication lag, repoints the database hostname, and marks the old primary for replacement. Your application reconnects to the same hostname; a well-configured driver pool retries and recovers without intervention. + +With `async` replication, writes that had not yet reached the promoted replica are lost in a failover. Use `sync` or `quorum` if that is unacceptable. + +# Manual failover {% #manual-failover %} + +Trigger a failover yourself, for example to test your application's recovery behavior. Optionally pass `targetReplicaId` to promote a specific replica. + +{% multicode %} +```server-nodejs +import { Client, Postgresql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +await postgresql.createFailover({ + databaseId: '<DATABASE_ID>', +}); +``` +```server-deno +import { Client, Postgresql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +await postgresql.createFailover({ + databaseId: '<DATABASE_ID>', +}); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Postgresql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$postgresql = new Postgresql($client); + +$postgresql->createFailover( + databaseId: '<DATABASE_ID>', +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.postgresql import Postgresql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +postgresql = Postgresql(client) + +postgresql.create_failover( + database_id='<DATABASE_ID>', +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +postgresql = Postgresql.new(client) + +postgresql.create_failover( + database_id: '<DATABASE_ID>', +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Postgresql postgresql = new Postgresql(client); + +await postgresql.CreateFailover( + databaseId: "<DATABASE_ID>" +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Postgresql postgresql = Postgresql(client); + +await postgresql.createFailover( + databaseId: '<DATABASE_ID>', +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Postgresql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val postgresql = Postgresql(client) + +postgresql.createFailover( + databaseId = "<DATABASE_ID>", +) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let postgresql = Postgresql(client) + +_ = try await postgresql.createFailover( + databaseId: "<DATABASE_ID>" +) +``` +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewPostgresql(client) + + _, err := service.CreateFailover("<DATABASE_ID>") + if err != nil { + panic(err) + } +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::postgresql::Postgresql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let postgresql = Postgresql::new(&client); + + postgresql.create_failover("<DATABASE_ID>", None).await?; + + Ok(()) +} +``` +```bash +curl -X POST \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <API_KEY>" \ + https://<REGION>.cloud.appwrite.io/v1/postgresql/<DATABASE_ID>/failovers +``` +{% /multicode %} + +# Reading from replicas {% #reads %} + +Replicas serve read traffic when [read/write splitting](/docs/products/databases/postgresql/connection-pooling#read-write-splitting) is enabled on the connection pooler. With `async` replication, a read that immediately follows a write can return stale data. Route reads that must see the latest write to the primary, or use `sync` replication. + +# Limits and billing {% #limits %} + +- Up to 5 replicas per database; the maximum depends on your plan. +- Each replica runs on the same specification as the primary and is billed as an add-on. See [pricing](/pricing). +- Replicas live in the same region as the primary. diff --git a/src/routes/docs/products/databases/postgresql/integrations/auth-js/+page.markdoc b/src/routes/docs/products/databases/postgresql/integrations/auth-js/+page.markdoc new file mode 100644 index 00000000000..f2feae0ebd2 --- /dev/null +++ b/src/routes/docs/products/databases/postgresql/integrations/auth-js/+page.markdoc @@ -0,0 +1,229 @@ +--- +layout: article +title: Auth.js +description: Use an Appwrite native PostgreSQL database as the backing store for Auth.js (NextAuth.js). Persist users, accounts, and sessions through a Prisma or Drizzle adapter, pooled from serverless runtimes. +--- + +[Auth.js](https://authjs.dev/) (formerly NextAuth.js) persists users, accounts, sessions, and verification tokens through a database adapter. When you configure an adapter, those records live in your own database instead of only in a cookie, which is what makes database sessions, account linking, and email sign-in possible. An Appwrite [native PostgreSQL database](/docs/products/databases/postgresql) is a standard PostgreSQL engine, so any Auth.js adapter built on a PostgreSQL ORM works against it with no Appwrite-specific configuration. + +{% info title="Before you start" %} +You'll need a native PostgreSQL database in a `ready` state and its credentials. See [native PostgreSQL databases](/docs/products/databases/postgresql) to create one, then open the database in the Console and click **Credentials**. The primary user is `admin`, and each database has its own generated database name. +{% /info %} + +# Choose an adapter {% #adapter %} + +Auth.js doesn't talk to the database directly, it goes through an official adapter. For a native PostgreSQL database, use whichever ORM you already run: + +- **Prisma** through [`@auth/prisma-adapter`](https://authjs.dev/getting-started/adapters/prisma). See the [Prisma guide](/docs/products/databases/postgresql/integrations/prisma) for the full datasource, pooling, and migration setup. +- **Drizzle** through [`@auth/drizzle-adapter`](https://authjs.dev/getting-started/adapters/drizzle). See the [Drizzle guide](/docs/products/databases/postgresql/integrations/drizzle) for the driver connection and `drizzle-kit` migration setup. + +The connection details, ports, and pooling behaviour are the same for both. The rest of this page shows the Prisma path and notes the Drizzle equivalents. + +# Set the connection string {% #connection-string %} + +Auth.js adapters read the database URL from the environment, exactly like any other ORM workload. Copy the connection string from the Console **Credentials** dialog or from `postgresql.get()` in the [API](/docs/products/databases/postgresql/connections#credentials), and give the adapter two URLs: a **pooled** one for the running app and a **direct** one for migrations. + +```env +# Runtime: pooled, transaction mode (prepared statements off) +DATABASE_URL="postgresql://admin:<password>@db-<hash>.<region>.appwrite.center:6432/<database>?sslmode=require&pgbouncer=true" + +# Migrations: direct connection to the engine +DIRECT_URL="postgresql://admin:<password>@db-<hash>.<region>.appwrite.center:5432/<database>?sslmode=require" + +# Development migrations: separate branch or database used only by Prisma Migrate +SHADOW_DATABASE_URL="postgresql://admin:<password>@db-<shadow-hash>.<region>.appwrite.center:5432/<database>?sslmode=require" +``` + +The app runtime connects on the [pooler](/docs/products/databases/postgresql/connection-pooling) port (`6432`), and schema migrations run over the direct engine port (`5432`). The TLS parameter (`sslmode=require`) is already part of the string Appwrite returns. The edge proxy terminates TLS, so no certificate setup is needed. For full certificate verification (`verify-full`) or mTLS, see the [Network](/docs/products/databases/postgresql/network-security) page. + +`SHADOW_DATABASE_URL` must point at a separate PostgreSQL database or branch. Prisma Migrate uses it during `migrate dev` to detect schema drift. It can reset the shadow target, so never set it to the same value as `DIRECT_URL`. `migrate deploy` does not use the shadow database. + +# Create the adapter schema {% #schema %} + +Auth.js ships a [canonical schema](https://authjs.dev/getting-started/database#models) of four core models, `User`, `Account`, `Session`, and `VerificationToken`. With Prisma, add them to `prisma/schema.prisma` and keep connection URLs in `prisma.config.ts` and your Prisma Client setup: + +```prisma +datasource db { + provider = "postgresql" +} +``` + +The generator and models are engine-agnostic: + +```prisma +generator client { + provider = "prisma-client-js" +} + +model User { + id String @id @default(cuid()) + name String? + email String? @unique + emailVerified DateTime? + image String? + accounts Account[] + sessions Session[] +} + +model Account { + id String @id @default(cuid()) + userId String + type String + provider String + providerAccountId String + refresh_token String? @db.Text + access_token String? @db.Text + expires_at Int? + token_type String? + scope String? + id_token String? @db.Text + session_state String? + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + + @@unique([provider, providerAccountId]) +} + +model Session { + id String @id @default(cuid()) + sessionToken String @unique + userId String + expires DateTime + user User @relation(fields: [userId], references: [id], onDelete: Cascade) +} + +model VerificationToken { + identifier String + token String + expires DateTime + + @@unique([identifier, token]) +} +``` + +Configure Prisma CLI commands in `prisma.config.ts`. The CLI uses `DIRECT_URL` because migrations need a direct session connection, while Prisma Client uses the pooled `DATABASE_URL` at runtime. + +```ts +import 'dotenv/config'; +import { defineConfig, env } from 'prisma/config'; + +export default defineConfig({ + schema: 'prisma/schema.prisma', + migrations: { + path: 'prisma/migrations', + }, + datasource: { + url: env('DIRECT_URL'), + shadowDatabaseUrl: process.env.SHADOW_DATABASE_URL, + }, +}); +``` + +With Drizzle, define the equivalent PostgreSQL tables in your schema file and generate a `drizzle-kit` migration instead. The table shapes are the same, and the official adapter docs include a ready-made PostgreSQL schema. + +# Run the migration over the direct connection {% #migrate %} + +Create the tables before the app serves any traffic. Prisma Migrate connects with `DIRECT_URL` (the engine port), so it gets a real session connection with full DDL privileges: + +```bash +npx prisma migrate dev --name authjs-init +``` + +In CI or production, apply already-generated migrations without prompting: + +```bash +npx prisma migrate deploy +``` + +If your build does not run `migrate dev`, generate Prisma Client explicitly: + +```bash +npx prisma generate +``` + +With Drizzle, run `drizzle-kit push` (or `migrate()`) against the same direct URL. The primary `admin` user owns the default database and can run schema changes. Narrower [connection users](/docs/products/databases/postgresql/connections#roles) (`readonly` / `readwrite`) intentionally cannot run DDL, so always migrate as `admin`. + +# Wire the adapter into Auth.js {% #config %} + +Create one Prisma Client with the PostgreSQL driver adapter, pointed at the pooled `DATABASE_URL`: + +```ts +import { PrismaPg } from '@prisma/adapter-pg'; +import { PrismaClient } from '@prisma/client'; + +const connectionString = process.env.DATABASE_URL; +if (!connectionString) throw new Error('DATABASE_URL is required'); + +const adapter = new PrismaPg({ connectionString }); + +export const prisma = new PrismaClient({ adapter }); +``` + +Pass the adapter to your Auth.js config through the `adapter` key. The adapter uses Prisma Client for every runtime read and write: + +```ts +import NextAuth from 'next-auth'; +import { PrismaAdapter } from '@auth/prisma-adapter'; +import { prisma } from '@/prisma'; + +export const { handlers, auth, signIn, signOut } = NextAuth({ + adapter: PrismaAdapter(prisma), + providers: [ + // your providers, e.g. GitHub, Google, Resend + ], +}); +``` + +The Drizzle equivalent is identical apart from the import, `adapter: DrizzleAdapter(db)` from `@auth/drizzle-adapter`, where `db` is your Drizzle instance. + +# Database vs JWT sessions {% #sessions %} + +Auth.js has two session strategies, and the adapter changes the default: + +- **`database`**: the default *once an adapter is configured*. A session row is written to the `Session` table and only an opaque session ID is stored in an `HttpOnly` cookie. Each request looks the session up in the native PostgreSQL database. Sessions can be revoked server-side. +- **`jwt`**: the default when no adapter is set. Session state lives entirely in a signed cookie, and the database is not read on the session path. + +You can set it explicitly: + +```ts +export const { handlers, auth } = NextAuth({ + adapter: PrismaAdapter(prisma), + session: { strategy: 'database' }, + providers: [], +}); +``` + +Even with `strategy: 'jwt'`, the adapter still persists users and linked accounts, so account linking and the admin view of users keep working; only the per-request session read moves off the database. + +# Pooling note {% #pooling %} + +On serverless and edge platforms (Vercel, Netlify, Cloudflare) every invocation is a fresh instance, so connecting straight to the engine fans out into more backend connections than it allows. Routing through the pooler in **transaction mode** (the default) absorbs that churn. Auth.js tables are write-light and read-heavy, exactly the access pattern transaction-mode pooling handles best, so the pooled `DATABASE_URL` above is the right default for the app runtime. + +Transaction mode does not hold a backend connection across statements, so server-side prepared statements are unavailable. The pooled Prisma URL carries `pgbouncer=true`, and Drizzle's `postgres.js` client should be created with `prepare: false`. Migrations always use the direct connection, so they keep a full session connection. If you need session-bound features, switch the pooler to **session mode**, see the [pooler modes](/docs/products/databases/postgresql/connection-pooling#modes) page for the trade-offs. + +# Use a branch for previews {% #branches %} + +[Branches](/docs/products/databases/postgresql/branches) are instant, isolated copies of a database with their own hostname and connection string, ideal for a pull-request preview or an integration-test job that signs users in and out against throwaway data: + +1. Create a branch from the API and read its `connectionString`. +2. Export the direct variant as `DIRECT_URL` and the pooled variant as `DATABASE_URL`. +3. Run `prisma migrate deploy` (or `drizzle-kit push`) and your auth flow against the branch. +4. Delete the branch when the job finishes. + +Because a branch starts from a storage snapshot, the Auth.js tables already exist with realistic data, so preview sign-ins behave like production without touching it. + +# Related {% #related %} + +{% cards %} +{% cards_item href="/docs/products/databases/postgresql/integrations/prisma" title="Prisma" %} +Datasource, pooled and direct URLs, and migrations for the Prisma adapter. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/integrations/drizzle" title="Drizzle" %} +Driver connection, pooler settings, and drizzle-kit migrations for PostgreSQL. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/connection-pooling" title="Connection pooler" %} +Transaction vs session mode, ports, and serverless connection handling. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/integrations/better-auth" title="Better Auth" %} +The same pattern for Better Auth on a native PostgreSQL database. +{% /cards_item %} +{% /cards %} diff --git a/src/routes/docs/products/databases/postgresql/integrations/better-auth/+page.markdoc b/src/routes/docs/products/databases/postgresql/integrations/better-auth/+page.markdoc new file mode 100644 index 00000000000..84a6f425d58 --- /dev/null +++ b/src/routes/docs/products/databases/postgresql/integrations/better-auth/+page.markdoc @@ -0,0 +1,147 @@ +--- +layout: article +title: Better Auth +description: Use an Appwrite native PostgreSQL database as the database for Better Auth. Point runtime traffic at the pooler, run schema generation and migrations over a direct connection, and store users and sessions in PostgreSQL. +--- + +[Better Auth](https://www.better-auth.com/) is a framework-agnostic authentication library for TypeScript that keeps its state, including users, sessions, accounts, and verification tokens, in a database you own. A native PostgreSQL database gives Better Auth a standard PostgreSQL engine, so you can use the connection string from the [Connections](/docs/products/databases/postgresql/connections) page and run the Better Auth CLI to create the schema. + +{% info title="Before you start" %} +You'll need a native PostgreSQL database in a `ready` state and its credentials. See [PostgreSQL databases](/docs/products/databases/postgresql) to create one, then open the database and click **Credentials** to copy values from the **Details**, **DSN**, **.env**, **Prisma**, **Drizzle**, or **psql** tab. The primary user is `admin`, and each database has its own generated database name. +{% /info %} + +# Set the connection strings {% #connection-strings %} + +Better Auth needs two connection strings for the same database: a **pooled** URL for your application runtime and a **direct** URL for schema work. Copy the values from the Console **Credentials** dialog, or fetch them with [`postgresql.get()`](/docs/products/databases/postgresql/connections#credentials), and put both in your environment. Never commit them. + +```env +# Runtime: pooler port (transaction mode), absorbs serverless connection churn +DATABASE_URL="postgresql://admin:<password>@db-<hash>.<region>.appwrite.center:6432/<database>?sslmode=require" + +# Schema generation & migrations: direct connection to the engine +DIRECT_URL="postgresql://admin:<password>@db-<hash>.<region>.appwrite.center:5432/<database>?sslmode=require" +``` + +Use `sslmode=require` for Appwrite Cloud connections. The edge proxy terminates TLS for every native PostgreSQL database, so drivers need no extra certificate configuration. See the [Network security](/docs/products/databases/postgresql/network-security) page for TLS and network controls. + +The PostgreSQL pooler runs on port `6432`, and the engine runs on port `5432`. See [Connections](/docs/products/databases/postgresql/connections) for connection details and the [connection pooler](/docs/products/databases/postgresql/connection-pooling#modes) page for the pool modes. + +# Configure Better Auth {% #configure %} + +Better Auth accepts either a **database instance** (a driver connection pool, which it drives through its built-in Kysely adapter) or an **ORM adapter** (Prisma, Drizzle, Kysely). Both work against a native PostgreSQL database. + +## With a driver pool {% #pool %} + +Pass a `pg` `Pool` pointed at the **pooled** URL so runtime traffic is multiplexed. Set `ssl: { rejectUnauthorized: true }` so the driver verifies the proxy's certificate: + +```ts +import { betterAuth } from 'better-auth'; +import { Pool } from 'pg'; + +export const auth = betterAuth({ + database: new Pool({ + connectionString: process.env.DATABASE_URL, + ssl: { rejectUnauthorized: true } + }), + emailAndPassword: { enabled: true } +}); +``` + +This is the simplest path: Better Auth manages the schema for you and can both generate and apply migrations through the CLI below. + +## With an ORM adapter {% #adapter %} + +If you already use an ORM, hand Better Auth an adapter instead of a raw `Pool`. Configure the ORM's own client against the native PostgreSQL database (pooled URL for the runtime client, direct URL for migrations), then wrap it: + +```ts +import { betterAuth } from 'better-auth'; +import { drizzleAdapter } from 'better-auth/adapters/drizzle'; +import { db } from './db'; + +export const auth = betterAuth({ + database: drizzleAdapter(db, { provider: 'pg' }), + emailAndPassword: { enabled: true } +}); +``` + +Set the ORM up against the native PostgreSQL database first, then return here for the schema steps. The [Prisma](/docs/products/databases/postgresql/integrations/prisma) and [Drizzle](/docs/products/databases/postgresql/integrations/drizzle) guides cover the `datasource`/client config, the pooled-vs-direct URL split, and how transaction-mode pooling affects prepared statements. + +# Generate and migrate the schema {% #migrate %} + +The [Better Auth CLI](https://www.better-auth.com/docs/concepts/cli) reads your `auth` config and creates the tables it needs. Run it with the **direct** URL so it gets a session connection with DDL privileges. Transaction-mode pooling is designed for short application transactions, not schema changes. + +Generate the schema for your setup. With a driver pool (built-in Kysely adapter) this produces a SQL file; with an ORM adapter it produces that ORM's schema (a Prisma schema, a Drizzle `schema.ts`): + +```bash +DATABASE_URL="$DIRECT_URL" npx @better-auth/cli@latest generate +``` + +If you're using the built-in adapter (a driver pool), apply the generated schema directly: + +```bash +DATABASE_URL="$DIRECT_URL" npx @better-auth/cli@latest migrate +``` + +`migrate` is only available for the built-in Kysely adapter. With a **Prisma** or **Drizzle** adapter, run `generate` to produce the schema, then apply it with that ORM's own migration tool, `prisma migrate deploy` or `drizzle-kit migrate`, again over `DIRECT_URL`. See the [Prisma](/docs/products/databases/postgresql/integrations/prisma#migrate) and [Drizzle](/docs/products/databases/postgresql/integrations/drizzle) guides for the exact commands. + +Both commands connect over the engine port, so they get full DDL privileges. The primary `admin` user owns the database and can run schema changes; narrower [database roles](/docs/products/databases/postgresql/connections#roles) (`readonly` / `readwrite`) intentionally cannot run DDL. + +# A minimal example {% #example %} + +After the schema exists, your runtime connects on the pooler URL and Better Auth handles the rest. Mount the handler for your framework and start creating users: + +```ts +import { auth } from './auth'; + +const result = await auth.api.signUpEmail({ + body: { + email: 'ada@example.com', + password: 'a-strong-password', + name: 'Ada Lovelace' + } +}); + +console.log(result.user.id); +``` + +On a long-running server, instantiate `auth` once and reuse it. On serverless, keep a single instance per module scope so warm invocations reuse it, and rely on the pooler to absorb cold-start connection churn. + +# Pooling and prepared statements {% #pooling %} + +Auth workloads, including sign-up, login, and session lookups, are short transactions, which is exactly what the pooler's default **transaction mode** is built for. Pointing your runtime pool at port `6432` lets a large number of serverless instances share a small backend pool. + +The one constraint of transaction mode is that it does not hold a backend connection across statements, so **server-side prepared statements are unavailable**. On PostgreSQL, the node-postgres `Pool` is fine with this out of the box. If you drive Better Auth through an ORM, disable prepared statements on the runtime client: with `postgres.js`, set `prepare: false`; with Prisma, add `pgbouncer=true` to the pooled URL. If your app needs prepared statements, advisory locks, or `LISTEN`/`NOTIFY`, switch the pooler to **session mode**. See the [pooler](/docs/products/databases/postgresql/connection-pooling#modes) page for the trade-offs. + +# Use a branch for previews and CI {% #branches %} + +[Branches](/docs/products/databases/postgresql/branches) are isolated copies of a database with their own hostname and connection string, ideal for running auth migrations against throwaway data in a pull-request preview or an integration-test job: + +1. Create a branch from the API and read its `connectionString`. +2. Export it as `DIRECT_URL` (and the pooled variant as `DATABASE_URL`). +3. Run the Better Auth CLI (or your ORM migration) and your test suite against the branch. +4. Delete the branch when the job finishes. + +Because a branch starts from a storage snapshot, the schema and data match the source database at branch time, so auth flows run against realistic data without touching production. + +# Related {% #related %} + +{% cards %} +{% cards_item href="/docs/products/databases/postgresql/connections" title="Connect" %} +Retrieve credentials, rotate the password, and create scoped connection users. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/connection-pooling" title="Connection pooler" %} +Pool modes, ports, and read/write splitting for serverless workloads. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/integrations/prisma" title="Prisma" %} +Drive the Better Auth Prisma adapter with pooled and direct URLs. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/integrations/drizzle" title="Drizzle" %} +Drive the Better Auth Drizzle adapter against a native PostgreSQL database. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/branches" title="Branches" %} +Ephemeral database copies for preview environments and CI. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/integrations/auth-js" title="Auth.js" %} +Use a native PostgreSQL database as the Auth.js (NextAuth) database. +{% /cards_item %} +{% /cards %} diff --git a/src/routes/docs/products/databases/postgresql/integrations/dbt/+page.markdoc b/src/routes/docs/products/databases/postgresql/integrations/dbt/+page.markdoc new file mode 100644 index 00000000000..2165f8b3295 --- /dev/null +++ b/src/routes/docs/products/databases/postgresql/integrations/dbt/+page.markdoc @@ -0,0 +1,114 @@ +--- +layout: article +title: dbt +description: Run dbt transformations against an Appwrite native PostgreSQL database. Configure profiles.yml for the direct engine port, size threads to your connection budget, and test models against a branch in CI. +--- + +An Appwrite native PostgreSQL database is a standard PostgreSQL server, so [dbt](https://docs.getdbt.com/) works against it through the standard [`dbt-postgres`](https://docs.getdbt.com/docs/local/connect-data-platform/postgres-setup) adapter with no Appwrite-specific configuration. Point a `profiles.yml` target at the connection details from the [Connections](/docs/products/databases/postgresql/connections) page and use `dbt debug`, `dbt run`, and `dbt build` the same way you would against any self-hosted PostgreSQL warehouse. + +dbt compiles your models into `CREATE TABLE` / `CREATE VIEW` statements and runs them in dependency order, materializing a transformed analytics layer inside a schema you control. + +{% info title="Before you start" %} +You'll need a native PostgreSQL database in a `ready` state and its credentials. See [PostgreSQL](/docs/products/databases/postgresql) to create one and [Connections](/docs/products/databases/postgresql/connections) to retrieve them. The primary user is `admin`, the database name is generated for each database, and the engine listens on port `5432`. +{% /info %} + +# Create a build schema {% #build-schema %} + +dbt issues DDL (`CREATE`, `DROP`, `ALTER`) to build your models, so connect with the primary `admin` user and build into a schema reserved for dbt, for example `analytics`. The `admin` user owns the generated database and can create the schema, tables, and views dbt needs. + +Keep transformed tables separate from source data by setting the `schema` field in `profiles.yml`. You can use different schema names per environment, such as `analytics_dev`, `analytics_ci`, and `analytics_prod`. + +# Configure profiles.yml {% #profiles %} + +dbt reads connection details from `~/.dbt/profiles.yml` or the project directory. Configure a `postgres` target against the database host on port `5432`, and set `sslmode: require` so the connection is encrypted: + +```yaml +analytics: + target: dev + outputs: + dev: + type: postgres + host: db-<hash>.<region>.appwrite.center + port: 5432 + user: admin + password: "{{ env_var('APPWRITE_DB_PASSWORD') }}" + dbname: <database> + schema: analytics + sslmode: require + threads: 4 +``` + +The dbt-postgres adapter uses `password` (not `pass`) and `dbname` (you may also write `database`). Read the password from an environment variable with `env_var` rather than committing it. The `schema` key is where dbt materializes models, set it to the build schema your user owns. + +The edge proxy terminates TLS for every native PostgreSQL database, so `sslmode: require` needs no extra certificate files. For full certificate verification, set `sslmode: verify-full` with `sslrootcert` pointing at a trusted root store, `system` on libpq 16+, or your OS bundle such as `/etc/ssl/certs/ca-certificates.crt`. The proxy's certificate is signed by a public CA, so there is no Appwrite-specific CA to download. + +# Test the connection {% #debug %} + +`dbt debug` validates your project files and opens a connection to confirm the credentials and host are correct: + +```bash +dbt debug +``` + +A successful run reports `Connection test: OK connection ok`. If it fails, recheck the host, port, `sslmode`, and password. + +# Run transformations {% #run %} + +Build your models into the analytics schema: + +```bash +dbt run +``` + +`dbt run` executes models only, materializing each as a table or view. Use `dbt build` to run models, tests, seeds, and snapshots together in DAG order, a failing test on an upstream model then skips its dependents: + +```bash +dbt build +``` + +# Choose the right connection {% #connection %} + +dbt opens one database connection per thread and uses each to run DDL and rely on session state (search paths, temporary objects, transactions spanning multiple statements). Point dbt at a connection that preserves that session: + +- **Direct engine port (`5432`)** is the simplest and recommended target. Each thread gets a backend session with full DDL privileges. This is what the `profiles.yml` above uses. +- **Session-mode pooler** also works, because it holds a backend connection for the whole client session. Connect on the pooler port (`6432`) and switch the pool to `session` mode. + +Do **not** point dbt at the **transaction-mode** pooler, which is the pooler default. Transaction mode returns the backend connection to the pool after every statement, so the session state and multi-statement DDL that dbt depends on can break. See the [connection pooling](/docs/products/databases/postgresql/connection-pooling#modes) page for the mode trade-offs. + +# Size threads to your connection budget {% #threads %} + +The `threads` setting controls how many models dbt builds in parallel, and dbt opens one connection per thread. A `threads: 8` run can hold up to eight backend connections at once. dbt also respects model dependencies, so it never runs more models concurrently than your DAG allows, regardless of the thread count. + +Pick a `threads` value that fits the connection budget for your database spec, and leave headroom for any application traffic sharing the same database. If you connect through a session-mode pooler, the same per-thread connections apply at the backend, so size against the pool, not the client side. Start at the adapter default of `4` and raise it only while connections stay within budget. + +# Test transformations against a branch {% #branches %} + +[Branches](/docs/products/databases/postgresql/branches) are isolated copies of a database with their own hostname and connection string. Because a branch starts from a storage snapshot, its schema and data match the source at branch time, so dbt models run against production-like data without touching production. That makes branches ideal for validating transformations in CI: + +1. Create a branch from the API and read its `connectionString`. +2. Set the branch host and credentials as the `profiles.yml` target (or export them as `env_var` values). +3. Run `dbt build` against the branch so models and tests execute on realistic data. +4. Delete the branch when the job finishes. + +This gives every pull request a clean, production-shaped warehouse to build against without touching live analytics tables. + +# Related {% #related %} + +{% cards %} +{% cards_item href="/docs/products/databases/postgresql/connections" title="Connections" %} +Retrieve credentials and rotate the primary password. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/connection-pooling" title="Connection pooler" %} +Pool modes and ports. Use session mode for dbt, never transaction mode. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/branches" title="Branches" %} +Ephemeral database copies for CI and preview environments. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/network-security" title="Network" %} +TLS modes, certificate verification, and IP allowlists. +{% /cards_item %} +{% /cards %} + +{% arrow_link href="https://docs.getdbt.com/docs/local/connect-data-platform/postgres-setup" %} +dbt-postgres adapter reference +{% /arrow_link %} diff --git a/src/routes/docs/products/databases/postgresql/integrations/django/+page.markdoc b/src/routes/docs/products/databases/postgresql/integrations/django/+page.markdoc new file mode 100644 index 00000000000..717b7ebdfd4 --- /dev/null +++ b/src/routes/docs/products/databases/postgresql/integrations/django/+page.markdoc @@ -0,0 +1,145 @@ +--- +layout: article +title: Django +description: Use Django's ORM with an Appwrite native PostgreSQL database. Configure the DATABASES setting with TLS options, run migrations on the direct PostgreSQL port, and tune persistent connections for pooling. +--- + +A native PostgreSQL database is a standard PostgreSQL engine, so Django's ORM works against it with no Appwrite-specific configuration. Point the `DATABASES` setting at the credentials from the [Connections](/docs/products/databases/postgresql/connections) page, then use migrations, models, and the rest of Django exactly as you would against any PostgreSQL server. + +{% info title="Before you start" %} +You'll need a native PostgreSQL database in a `ready` state and its credentials. See [native PostgreSQL databases](/docs/products/databases/postgresql) to create one and [Connections](/docs/products/databases/postgresql/connections) to retrieve the connection details. The primary user is `admin`, and the database name is generated for each database. +{% /info %} + +# Install a driver {% #driver %} + +Django talks to PostgreSQL through a driver. Use [psycopg 3](https://www.psycopg.org/psycopg3/): + +```bash +pip install "psycopg[binary]" +``` + +Django's PostgreSQL backend uses the `ENGINE` value `django.db.backends.postgresql`. + +# Configure `DATABASES` {% #databases %} + +In `settings.py`, point the `default` connection at your native PostgreSQL database and require TLS through `OPTIONS`. Appwrite Cloud terminates TLS at the edge, and the certificate is signed by a public certificate authority. Read every value from the environment so credentials stay out of source control: + +```python +import os + +DATABASES = { + "default": { + "ENGINE": "django.db.backends.postgresql", + "NAME": os.environ["DB_NAME"], + "USER": os.environ["DB_USER"], + "PASSWORD": os.environ["DB_PASSWORD"], + "HOST": os.environ["DB_HOST"], + "PORT": os.environ["DB_PORT"], + "OPTIONS": { + "sslmode": "require", + }, + } +} +``` + +The PostgreSQL backend forwards everything in `OPTIONS` to the driver's connection, so `sslmode` is honored the same way `psql` honors it in a connection string. For full certificate verification, set `"sslmode": "verify-full"` with `"sslrootcert"` pointing at a trusted root store or your OS bundle, such as `/etc/ssl/certs/ca-certificates.crt`. See [Network security](/docs/products/databases/postgresql/network-security) for TLS and IP allowlist guidance. + +Populate the environment from the Console **Credentials** dialog or from `postgresql.get()` in the [API credentials flow](/docs/products/databases/postgresql/connections#credentials): + +```env +DB_NAME=<database> +DB_USER=admin +DB_PASSWORD=<password> +DB_HOST=db-<hash>.<region>.appwrite.center +DB_PORT=5432 +``` + +Port `5432` is the direct PostgreSQL port. Keep migrations on this port, and see [pooling](#pooling) below for when to add the pooler. + +# Run migrations {% #migrate %} + +Generate migrations from your models, then apply them against the direct PostgreSQL port: + +```bash +python manage.py makemigrations +python manage.py migrate +``` + +`migrate` needs a session connection with DDL privileges. The primary `admin` user owns the database and can run schema changes. Narrower [database roles](/docs/products/databases/postgresql/connections#roles) (`readonly` or `readwrite`) are intended for application traffic with reduced privileges. Always run `migrate` on the direct PostgreSQL port, not through the transaction-mode pooler. + +# Define a model {% #model %} + +Models map to tables in your native PostgreSQL database. Define one in an app's `models.py`: + +```python +from django.db import models + +class Article(models.Model): + title = models.CharField(max_length=200) + body = models.TextField() + created_at = models.DateTimeField(auto_now_add=True) + + class Meta: + ordering = ["-created_at"] +``` + +Run `makemigrations` and `migrate` again to create the table, then query it through the ORM: + +```python +from blog.models import Article + +Article.objects.create(title="Hello", body="First post") + +recent = Article.objects.order_by("-created_at")[:10] +``` + +# Persistent connections and pooling {% #pooling %} + +By default Django opens a new connection per request (`CONN_MAX_AGE = 0`). On a long-running WSGI server (Gunicorn, uWSGI) you can reuse connections by raising it. Each worker thread keeps its own connection, so the database must allow at least as many connections as you run worker threads: + +```python +DATABASES["default"]["CONN_MAX_AGE"] = 60 +DATABASES["default"]["CONN_HEALTH_CHECKS"] = True +``` + +`CONN_HEALTH_CHECKS` revalidates a reused connection once per request, avoiding errors after an engine restart. Do not enable persistent connections under the development server, it spawns a thread per request and gains nothing, and disable them under ASGI. + +{% info title="Persistent connections need a session" %} +A worker holding a connection across requests behaves like a long-lived session. Connect it to the direct PostgreSQL port or the **session-mode** pooler. The default **transaction-mode** pooler can hand each statement a different backend connection, which makes it a better fit for serverless and short-lived runtimes that open and close a connection per invocation. +{% /info %} + +If you front the database with the transaction-mode [connection pooler](/docs/products/databases/postgresql/connection-pooling), point `HOST` and `PORT` at the PostgreSQL pooler on port `6432`. Also set `DISABLE_SERVER_SIDE_CURSORS = True`, since server-side cursors can't survive being moved between backend connections: + +```python +DATABASES["default"]["DISABLE_SERVER_SIDE_CURSORS"] = True +``` + +For prepared statements, advisory locks, `LISTEN`/`NOTIFY`, or temporary tables, use **session mode** instead, see the [pooler](/docs/products/databases/postgresql/connection-pooling#modes) page for the trade-offs. + +# Use a branch for previews and CI {% #branches %} + +[Branches](/docs/products/databases/postgresql/branches) are instant, isolated copies of a database with their own hostname and connection details. They're ideal for running migrations against throwaway data in a pull-request preview or an integration-test job: + +1. Create a branch from the API and read its connection details. +2. Export them as the `DB_*` environment variables your settings read. +3. Run `python manage.py migrate` and your test suite against the branch. +4. Delete the branch when the job finishes. + +Because a branch starts from a storage snapshot, its schema and data match the source database at branch time, so migrations run against realistic data without touching production. + +# Related {% #related %} + +{% cards %} +{% cards_item href="/docs/products/databases/postgresql/connections" title="Connections" %} +Retrieve credentials, rotate the password, and create scoped database roles. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/connection-pooling" title="Connection pooler" %} +Pool modes, ports, and read/write splitting for serverless workloads. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/branches" title="Branches" %} +Ephemeral database copies for preview environments and CI. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/network-security" title="Network" %} +TLS, certificate verification, IP allowlists, and idle timeout settings. +{% /cards_item %} +{% /cards %} diff --git a/src/routes/docs/products/databases/postgresql/integrations/drivers/+page.markdoc b/src/routes/docs/products/databases/postgresql/integrations/drivers/+page.markdoc new file mode 100644 index 00000000000..39897535fb8 --- /dev/null +++ b/src/routes/docs/products/databases/postgresql/integrations/drivers/+page.markdoc @@ -0,0 +1,197 @@ +--- +layout: article +title: Node.js drivers +description: Connect to an Appwrite native PostgreSQL database from Node.js with node-postgres or postgres.js. Configure pools, TLS verification, serverless connection management, and troubleshooting. +--- + +A native PostgreSQL database is a standard PostgreSQL engine, so any Node.js driver that speaks the PostgreSQL wire protocol can connect over TLS without an Appwrite-specific adapter. The [Connections](/docs/products/databases/postgresql/connections#drivers) page shows the minimal snippet to run your first query. This page covers production pool configuration, certificate verification, serverless connection management, and common connection errors. + +{% info title="Before you start" %} +You'll need a native PostgreSQL database in a `ready` state and its credentials. In the Console, open the database and click **Credentials**. Use the **Details** tab for individual values, or the **DSN**, **.env**, **Prisma**, **Drizzle**, or **psql** tab for a ready-made snippet. The primary user is `admin`, and the database name is generated for each database. Keep the password in an environment variable and never commit it. +{% /info %} + +# Raw driver, ORM, or SQL API? {% #choosing %} + +There are three common ways to reach a native PostgreSQL database from Node.js. Pick by workload: + +| Approach | Use it when | +|------------------------------|----------------------------------------------------------------------------------------------| +| **Raw driver** (this page) | You want a connection pool you control, hot-path queries, or a thin data layer with little overhead. | +| **ORM** ([Prisma](/docs/products/databases/postgresql/integrations/prisma), [Drizzle](/docs/products/databases/postgresql/integrations/drizzle)) | You want migrations, a typed schema, and query building. The ORM still uses a PostgreSQL driver underneath. | +| **[SQL API](/docs/products/databases/postgresql/quick-start#first-queries)** | You're on an edge runtime that cannot hold a TCP socket, or scripting a one-off query over HTTPS. | + +The rest of this page is about raw drivers on a long-running or serverless Node.js server that can open TCP connections. + +# node-postgres (pg) {% #node-postgres %} + +For a long-running server, create one `Pool` at startup and reuse it for every request. The pool opens connections lazily up to `max` and hands them back to your handlers. + +```js +import { Pool } from 'pg'; +import process from 'node:process'; + +const pool = new Pool({ + host: 'db-<hash>.<region>.appwrite.center', + port: 5432, + user: 'admin', + password: process.env.DB_PASSWORD, + database: '<database>', + ssl: { rejectUnauthorized: true }, + max: 10, + idleTimeoutMillis: 30000, + connectionTimeoutMillis: 5000, +}); + +const { rows } = await pool.query('SELECT id, email FROM users WHERE id = $1', [userId]); +``` + +Pool sizing is a budget. Each connection in `max`, across every running instance, counts against your specification's connection cap. A single app server with `max: 10` is fine; ten replicas with `max: 50` each is 500 connections and can exhaust many specifications. Size `max` to the connection cap divided by replica count, then put the [connection pooler](/docs/products/databases/postgresql/connection-pooling) in front if you need more client concurrency than that allows. + +`ssl: { rejectUnauthorized: true }` validates the server certificate against Node's built-in CA store. The edge proxy presents a certificate signed by a well-known public CA, so this works without supplying your own bundle. See [TLS and CA verification](#tls) for custom CA bundles and mTLS. + +## Pooled port vs direct port {% #pg-ports %} + +The pooler defaults to **transaction mode**, which does not hold a backend connection across statements, so server-side prepared statements are unavailable. In node-postgres, a query becomes a server-side prepared statement only when you pass a `name` field on the query config: + +```js +// Safe on the pooler (port 6432, transaction mode): no `name`, no server-side prepared statement. +await pool.query('SELECT * FROM events WHERE user_id = $1', [userId]); + +// Use the direct port or session-mode pooler for named prepared statements. +await pool.query({ name: 'fetch-events', text: 'SELECT * FROM events WHERE user_id = $1', values: [userId] }); +``` + +Parameterized queries without a `name` are sent fresh each time and work on the pooled port. If you rely on named prepared statements, advisory locks, `LISTEN`/`NOTIFY`, temporary tables, or `SET LOCAL`, connect on the direct port (`5432`) or switch the pooler to **session mode**. See the [pooler modes](/docs/products/databases/postgresql/connection-pooling#modes) page for the trade-offs. Run migrations on the direct port. + +# postgres.js {% #postgres-js %} + +`postgres.js` (the `postgres` package) takes its own option names. Create the client once at module scope: + +```js +import postgres from 'postgres'; +import process from 'node:process'; + +const sql = postgres({ + host: 'db-<hash>.<region>.appwrite.center', + port: 5432, + username: 'admin', + password: process.env.DB_PASSWORD, + database: '<database>', + ssl: 'verify-full', + max: 10, + idle_timeout: 30, + connect_timeout: 10, +}); + +const users = await sql`SELECT id, email FROM users WHERE id = ${userId}`; +``` + +`ssl: 'verify-full'` enables TLS and verifies the server certificate against the system CA store. If your runtime image ships without one, pass an object with a public CA bundle instead: `ssl: { rejectUnauthorized: true, ca: fs.readFileSync('./ca-bundle.crt') }`. + +When you point `postgres.js` at the **pooler port** (`6432`) in transaction mode, disable prepared statements. The library uses prepared statements by default, and documents `prepare: false` for PgBouncer transaction mode: + +```js +const sql = postgres({ + host: 'db-<hash>.<region>.appwrite.center', + port: 6432, + username: 'admin', + password: process.env.DB_PASSWORD, + database: '<database>', + ssl: 'verify-full', + prepare: false, + max: 5, +}); +``` + +Leave `prepare` at its default when you connect on the direct port or use the pooler in session mode. + +# TLS and CA verification {% #tls %} + +Connections on Appwrite Cloud are encrypted with TLS, terminated at the edge and forwarded to your database over the internal network. The connection string from the credentials dialog carries the right SSL settings for your environment, and the examples above use strict certificate verification. + +| Level | node-postgres | postgres.js | +|----------------------------------------------|-------------------------------------------------|--------------------------------------------------| +| **Encrypt and verify CA** | `ssl: { rejectUnauthorized: true }` | `ssl: 'verify-full'` | +| **Custom CA bundle** (no system trust store) | `ssl: { rejectUnauthorized: true, ca: fs.readFileSync('./ca-bundle.crt') }` | `ssl: { rejectUnauthorized: true, ca: fs.readFileSync('./ca-bundle.crt') }` | + +The certificate behind every database hostname is signed by a well-known public CA, so Appwrite does not require a custom CA download. The `ca` option is useful for runtimes without a system trust store, such as distroless or scratch images. Point it at a standard public CA bundle from your base image's `ca-certificates` package or [Mozilla's bundle](https://curl.se/docs/caextract.html): + +```js +import fs from 'node:fs'; + +const ssl = { + rejectUnauthorized: true, + ca: fs.readFileSync('./ca-bundle.crt'), +}; +``` + +When the CA comes from an environment variable, restore the newlines the variable strips: + +```js +const ssl = { + rejectUnauthorized: true, + ca: process.env.DB_SSL_CA?.replace(/\\n/g, '\n'), +}; +``` + +Do not ship `rejectUnauthorized: false` to production. It disables certificate validation and exposes the connection to interception. To require **mTLS**, where the client also presents a certificate, see the [Network security](/docs/products/databases/postgresql/network-security) page. Then add `key` and `cert` alongside `ca` in the same `ssl` object. + +# Serverless connection management {% #serverless %} + +On Lambda, Cloud Run, Vercel, and similar platforms, every cold start is a fresh instance with its own pool. A `max: 10` pool times 200 concurrent instances is 2,000 backend connections, which is more than most specifications allow. Let Appwrite's pooler absorb the fan-out: + +- **Connect on the pooler port** (`6432`) in transaction mode. +- **Keep the per-instance pool tiny**, usually `max: 1` or `2`. One invocation rarely needs more than one connection at a time. +- **Create the client once per module scope** so warm invocations reuse it. +- **Disable per-connection prepared statements** on the pooled port: `prepare: false` for postgres.js, and avoid `name` on node-postgres query configs. + +```js +import postgres from 'postgres'; +import process from 'node:process'; + +// Module scope: reused across warm invocations. +const sql = postgres({ + host: 'db-<hash>.<region>.appwrite.center', + port: 6432, + username: 'admin', + password: process.env.DB_PASSWORD, + database: '<database>', + ssl: 'verify-full', + prepare: false, + max: 1, +}); + +export async function handler(event) { + const rows = await sql`SELECT id FROM users WHERE email = ${event.email}`; + return rows[0] ?? null; +} +``` + +On **edge runtimes** (Cloudflare Workers, Vercel Edge, Deno Deploy), raw TCP sockets are usually unavailable. Use the [SQL API](/docs/products/databases/postgresql/quick-start#first-queries) for these workloads. + +# Troubleshooting {% #troubleshooting %} + +| Symptom | Cause and fix | +|-------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------| +| `self-signed certificate` / `unable to verify the first certificate` | TLS is reaching the wrong host, or the runtime has a stale or incomplete `ca` bundle. The proxy's certificate is signed by a public CA. Use driver certificate verification with the system trust store, and supply a current public CA bundle only when the runtime has no system trust store. | +| `sorry, too many clients already` / connection attempts rejected at the proxy | Aggregate pool size across all instances exceeds the database specification's connection cap. Lower `max`, or move to the [pooler](/docs/products/databases/postgresql/connection-pooling) port and shrink the per-instance pool to 1 or 2. | +| `prepared statement "S_1" does not exist` / `unnamed prepared statement does not exist` | Server-side prepared statements on the pooler in transaction mode. Set `prepare: false` for postgres.js, drop the `name` field for node-postgres, or use the direct port or [session mode](/docs/products/databases/postgresql/connection-pooling#modes). | +| `ETIMEDOUT` / `connection timed out` on connect | The database may be cold-starting on smaller specifications or blocked by an [IP allowlist](/docs/products/databases/postgresql/network-security#ip-allowlist). Confirm your egress IP is allowed and raise `connectionTimeoutMillis` or `connect_timeout` to absorb cold starts. | +| Connections drop after a period of inactivity | The proxy closes idle connections after `networkIdleTimeoutSeconds`. Keep `idleTimeoutMillis` and `idle_timeout` below that window so the driver recycles before the proxy does, or enable keep-alive. | + +# Related {% #related %} + +{% cards %} +{% cards_item href="/docs/products/databases/postgresql/connections" title="Connections" %} +Retrieve credentials, rotate the password, and create scoped connection users. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/connection-pooling" title="Connection pooler" %} +Pool modes, ports, and read/write splitting for serverless workloads. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/quick-start#first-queries" title="SQL API" %} +Run SQL over HTTPS with no TCP connection for edge runtimes and scripts. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/network-security" title="Network security" %} +TLS, certificate verification, mTLS, and IP allowlists. +{% /cards_item %} +{% /cards %} diff --git a/src/routes/docs/products/databases/postgresql/integrations/drizzle/+page.markdoc b/src/routes/docs/products/databases/postgresql/integrations/drizzle/+page.markdoc new file mode 100644 index 00000000000..09c9b64105f --- /dev/null +++ b/src/routes/docs/products/databases/postgresql/integrations/drizzle/+page.markdoc @@ -0,0 +1,193 @@ +--- +layout: article +title: Drizzle +description: Use Drizzle ORM with an Appwrite native PostgreSQL database. Configure the driver, run migrations against the direct connection, and pool runtime traffic from serverless environments. +--- + +Appwrite's native PostgreSQL database is a standard PostgreSQL engine, so [Drizzle ORM](https://orm.drizzle.team/) works against it with no Appwrite-specific configuration. Point Drizzle's driver at the connection string from the [Connections](/docs/products/databases/postgresql/connections) page and use Drizzle Kit, the query builder, and the rest of the toolchain as you would against any PostgreSQL server. + +{% info title="Before you start" %} +You'll need a native PostgreSQL database in a `ready` state and its credentials. See [native PostgreSQL databases](/docs/products/databases/postgresql) to create one and [Connections](/docs/products/databases/postgresql/connections) to retrieve the connection string. The primary user is `admin`, and the database name is generated per database. +{% /info %} + +# Set the connection string {% #connection-string %} + +In the Console, open your database and click **Credentials**. Copy the connection string from the **DSN**, **.env**, or **Drizzle** tab, or fetch it with [`postgresql.get()`](/docs/products/databases/postgresql/connections#credentials). Put it in your environment, never commit it: + +```env +DATABASE_URL="postgresql://admin:<password>@db-<hash>.<region>.appwrite.center:5432/<database>?sslmode=require" +``` + +The TLS parameter (`sslmode=require`) is part of the connection string Appwrite returns. Appwrite Cloud terminates TLS at the edge and forwards traffic to your database over the internal network, so no extra certificate configuration is needed. For full certificate verification (`verify-full`) or mTLS, see [Network security](/docs/products/databases/postgresql/network-security). + +# Install and configure the driver {% #driver %} + +Drizzle talks to PostgreSQL through one of two driver packages. Pick the one already in your stack: + +```bash +# node-postgres +npm install drizzle-orm pg +npm install -D drizzle-kit @types/pg + +# or postgres.js +npm install drizzle-orm postgres +npm install -D drizzle-kit +``` + +With **node-postgres**, import `drizzle` from `drizzle-orm/node-postgres` and hand it the connection string: + +```ts +import { drizzle } from 'drizzle-orm/node-postgres'; + +export const db = drizzle(process.env.DATABASE_URL!); +``` + +With **postgres.js**, import `drizzle` from `drizzle-orm/postgres-js`. For a direct connection to the engine you can pass the URL straight through: + +```ts +import { drizzle } from 'drizzle-orm/postgres-js'; + +export const db = drizzle(process.env.DATABASE_URL!); +``` + +When you pool through the connection pooler in transaction mode (see [Pool connections from serverless](#pooling)), postgres.js must disable prepared statements. Build the client yourself with `prepare: false` and pass it to `drizzle`: + +```ts +import { drizzle } from 'drizzle-orm/postgres-js'; +import postgres from 'postgres'; + +const client = postgres(process.env.DATABASE_URL!, { prepare: false }); + +export const db = drizzle({ client }); +``` + +Define your tables in a schema file Drizzle Kit can read: + +```ts +import { pgTable, serial, text, timestamp } from 'drizzle-orm/pg-core'; + +export const users = pgTable('users', { + id: serial('id').primaryKey(), + email: text('email').notNull().unique(), + createdAt: timestamp('created_at').notNull().defaultNow() +}); +``` + +# Configure Drizzle Kit {% #config %} + +Drizzle Kit reads `drizzle.config.ts` for migrations and introspection. Set the `dialect`, point `schema` at your table definitions, and pass the connection string through `dbCredentials`: + +```ts +import { defineConfig } from 'drizzle-kit'; + +export default defineConfig({ + dialect: 'postgresql', + schema: './src/schema.ts', + out: './drizzle', + dbCredentials: { + url: process.env.DATABASE_URL! + } +}); +``` + +# Run migrations {% #migrate %} + +Generate SQL migration files from your schema, then apply them: + +```bash +npx drizzle-kit generate +npx drizzle-kit migrate +``` + +`generate` diffs your schema against the last snapshot and writes a timestamped `.sql` file into the `out` directory; `migrate` applies any pending files to the database. Point Drizzle Kit at the **direct** engine port (`5432`), not the pooler, because migrations issue DDL that needs a session-level connection. The primary `admin` user owns the generated database and can run schema changes. Use narrower [database roles](/docs/products/databases/postgresql/connections#roles) for application traffic that does not need DDL privileges. + +To apply migrations from your application at startup instead of the CLI, use the matching `migrate` helper for your driver: + +```ts +import { migrate } from 'drizzle-orm/node-postgres/migrator'; +import { db } from './db'; + +await migrate(db, { migrationsFolder: './drizzle' }); +``` + +# Query with Drizzle {% #query %} + +Once the schema is migrated, use the query builder: + +```ts +import { desc } from 'drizzle-orm'; +import { db } from './db'; +import { users } from './schema'; + +const [user] = await db + .insert(users) + .values({ email: 'ada@example.com' }) + .returning(); + +const recent = await db + .select() + .from(users) + .orderBy(desc(users.createdAt)) + .limit(10); +``` + +On long-running servers, create the `db` instance once at module scope and reuse it. On serverless, keep a single instance per module scope so warm invocations reuse it, and rely on the pooler to absorb cold-start connection churn. + +# Pool connections from serverless {% #pooling %} + +Each running instance opens its own connections to the engine. On serverless and edge platforms (Vercel, Netlify, Cloudflare), short-lived instances can fan out into more backend connections than the engine allows. Route runtime traffic through the [connection pooler](/docs/products/databases/postgresql/connection-pooling) by connecting on the pooler port (`6432`) on the same hostname. + +The pooler defaults to **transaction mode**, which does not keep a backend connection across statements, so server-side prepared statements are unavailable. Keep `drizzle.config.ts` and the startup migrator pointed at `DIRECT_URL` so DDL still runs over a session-level connection: + +```env +# Runtime: pooled, transaction mode +DATABASE_URL="postgresql://admin:<password>@db-<hash>.<region>.appwrite.center:6432/<database>?sslmode=require" + +# Migrations & introspection: direct connection to the engine +DIRECT_URL="postgresql://admin:<password>@db-<hash>.<region>.appwrite.center:5432/<database>?sslmode=require" +``` + +With **postgres.js**, disable prepared statements by building the client with `prepare: false`, as shown in [Install and configure the driver](#driver). + +```ts +import { defineConfig } from 'drizzle-kit'; + +export default defineConfig({ + dialect: 'postgresql', + schema: './src/schema.ts', + out: './drizzle', + dbCredentials: { + url: process.env.DIRECT_URL! + } +}); +``` + +If your application relies on prepared statements, advisory locks, `LISTEN`/`NOTIFY`, temporary tables, or `SET LOCAL`, switch the pooler to **session mode** and remove `prepare: false` with postgres.js. See the [pooler](/docs/products/databases/postgresql/connection-pooling#modes) page for the trade-offs. + +# Use a branch for previews and CI {% #branches %} + +[Branches](/docs/products/databases/postgresql/branches) are isolated copies of a database with their own hostname and connection string. They're ideal for running migrations against throwaway data in a pull-request preview or an integration-test job: + +1. Create a branch from the API and read its `connectionString`. +2. Export it as `DIRECT_URL` (and the pooled variant as `DATABASE_URL`). +3. Run `drizzle-kit migrate` and your test suite against the branch. +4. Delete the branch when the job finishes. + +Because a branch starts from a storage snapshot, the schema and data match the source database at branch time, so migrations run against realistic data without touching production. + +# Related {% #related %} + +{% cards %} +{% cards_item href="/docs/products/databases/postgresql/connections" title="Connections" %} +Retrieve credentials, rotate the password, and create database roles. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/connection-pooling" title="Connection pooler" %} +Pool modes, ports, and read/write splitting for serverless workloads. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/branches" title="Branches" %} +Ephemeral database copies for preview environments and CI. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/network-security" title="Network security" %} +TLS modes, certificate verification, mTLS, and IP allowlists. +{% /cards_item %} +{% /cards %} diff --git a/src/routes/docs/products/databases/postgresql/integrations/ef-core/+page.markdoc b/src/routes/docs/products/databases/postgresql/integrations/ef-core/+page.markdoc new file mode 100644 index 00000000000..b362344b0d9 --- /dev/null +++ b/src/routes/docs/products/databases/postgresql/integrations/ef-core/+page.markdoc @@ -0,0 +1,168 @@ +--- +layout: article +title: EF Core +description: Use Entity Framework Core with an Appwrite native PostgreSQL database. Configure the Npgsql connection string, run migrations against the direct PostgreSQL host, and rely on the driver's built-in connection pool from an ASP.NET server. +--- + +A native PostgreSQL database is a standard PostgreSQL engine, so [Entity Framework Core](https://learn.microsoft.com/ef/core/) works against it with no Appwrite-specific configuration. Point the Npgsql EF Core provider at the connection string from the [Connections](/docs/products/databases/postgresql/connections) page and use `DbContext`, migrations, and the rest of the toolchain exactly as you would against any self-hosted PostgreSQL server. + +{% info title="Before you start" %} +You'll need a native PostgreSQL database in a `ready` state and its credentials. See [native PostgreSQL databases](/docs/products/databases/postgresql) to create one and [Connections](/docs/products/databases/postgresql/connections) to retrieve the connection details. Appwrite provides the generated database name, primary username `admin`, and password in the Console. +{% /info %} + +# Install the provider {% #install %} + +Add the EF Core provider for PostgreSQL: + +```bash +dotnet add package Npgsql.EntityFrameworkCore.PostgreSQL +``` + +Then add the EF Core design-time package (used by the `dotnet ef` tools) and install the CLI tool: + +```bash +dotnet add package Microsoft.EntityFrameworkCore.Design + +dotnet tool install --global dotnet-ef +``` + +If your app targets an older framework than the current .NET release, pin the packages to the matching major version instead, for example `--version 8.*` for a .NET 8 app. + +# Set the connection string {% #connection-string %} + +ADO.NET providers use key/value connection strings rather than a URL. Store it in `appsettings.json` under `ConnectionStrings`, and keep the password out of source control (use [user secrets](https://learn.microsoft.com/aspnet/core/security/app-secrets) or an environment variable in deployments): + +```json +{ + "ConnectionStrings": { + "Default": "Host=db-<hash>.<region>.appwrite.center;Port=5432;Database=<database>;Username=admin;Password=<password>;SSL Mode=Require" + } +} +``` + +The edge proxy terminates TLS for every native PostgreSQL database, so `SSL Mode=Require` is all you need. `Require` encrypts the connection without validating the server certificate hostname. For full certificate verification, set `SSL Mode=VerifyFull`: Npgsql validates the chain and hostname against the operating system's trusted roots, and the proxy's certificate is signed by a public CA those roots already include, so no `Root Certificate` parameter is needed: + +```text +Host=...;Port=5432;Database=<database>;Username=admin;Password=<password>;SSL Mode=VerifyFull +``` + +# Configure the DbContext {% #dbcontext %} + +Define your model and a `DbContext`. The model is ordinary EF Core code, and the provider-specific call comes when you register the context in `Program.cs`: + +```csharp +using Microsoft.EntityFrameworkCore; + +public class User +{ + public int Id { get; set; } + public string Email { get; set; } = string.Empty; + public DateTime CreatedAt { get; set; } = DateTime.UtcNow; +} + +public class AppDbContext : DbContext +{ + public AppDbContext(DbContextOptions<AppDbContext> options) + : base(options) { } + + public DbSet<User> Users => Set<User>(); +} +``` + +# Run migrations {% #migrate %} + +Migrations need a session connection and full DDL privileges, so always run them against the direct PostgreSQL host on port `5432`, not the [pooler](/docs/products/databases/postgresql/connection-pooling). The primary `admin` user owns the database; narrower [connection users](/docs/products/databases/postgresql/connections) (`readonly` / `readwrite`) intentionally cannot run DDL. + +Create the first migration, then apply it: + +```bash +dotnet ef migrations add InitialCreate + +dotnet ef database update +``` + +`dotnet ef database update` reads the same `Default` connection string and applies any pending migrations, recording each in the `__EFMigrationsHistory` table so it only applies new ones next time. In CI or production, prefer generating an idempotent SQL script with `dotnet ef migrations script --idempotent` and applying it as a deploy step. + +# Wire up an ASP.NET server {% #aspnet %} + +Register the `DbContext` in `Program.cs`, reading the connection string with `GetConnectionString`. A long-running ASP.NET server should connect to the direct PostgreSQL host and let the provider manage its own pool: + +Call `UseNpgsql(...)` with the connection string. This is the single entry point for all Npgsql options: + +```csharp +using Microsoft.EntityFrameworkCore; + +var builder = WebApplication.CreateBuilder(args); + +builder.Services.AddDbContext<AppDbContext>(options => + options.UseNpgsql(builder.Configuration.GetConnectionString("Default"))); +``` + +The route handlers use ordinary EF Core queries: + +```csharp +var app = builder.Build(); + +app.MapGet("/users", async (AppDbContext db) => + await db.Users.OrderByDescending(u => u.CreatedAt).Take(10).ToListAsync()); + +app.MapPost("/users", async (AppDbContext db, string email) => +{ + var user = new User { Email = email }; + db.Users.Add(user); + await db.SaveChangesAsync(); + return Results.Created($"/users/{user.Id}", user); +}); + +app.Run(); +``` + +# Connection pooling {% #pooling %} + +Npgsql has a built-in connection pool, enabled by default. Each process keeps its own pool keyed on the connection string, so a long-running ASP.NET server usually connects directly to PostgreSQL and tunes the driver pool with the connection string: + +```text +Host=...;Port=5432;Database=<database>;Username=admin;Password=<password>;SSL Mode=Require;Maximum Pool Size=50 +``` + +Set `Maximum Pool Size` to cap concurrent backend connections per process (Npgsql defaults to `100`). + +Keep the sum across all your processes under the engine's connection limit for the database's specification. + +If you instead run many short-lived instances (serverless functions, per-request containers) that each open their own pool, route them through the Appwrite [connection pooler](/docs/products/databases/postgresql/connection-pooling) on port `6432` to fan many clients onto a small backend pool. The pooler defaults to **transaction mode**, which doesn't hold a backend connection across statements, so server-side prepared statements aren't available: + +Disable Npgsql's automatic prepared statements with `Max Auto Prepare=0` when connecting to the transaction-mode pooler: + +```text +Host=...;Port=6432;Database=<database>;Username=admin;Password=<password>;SSL Mode=Require;Max Auto Prepare=0 +``` + +If your application relies on prepared statements, advisory locks, or `LISTEN`/`NOTIFY`, switch the pooler to **session mode** instead, see the [pooler](/docs/products/databases/postgresql/connection-pooling#modes) page for the trade-offs. + +# Use a branch for previews and CI {% #branches %} + +Database [branches](/docs/products/databases/postgresql/branches) are instant, isolated copies of a database with their own hostname and credentials. They're ideal for running migrations against throwaway data in a pull-request preview or an integration-test job: + +1. Create a branch from the API and read its connection details. +2. Build the connection string for the branch host and pass it as the `Default` connection string. +3. Run `dotnet ef database update` and your test suite against the branch. +4. Delete the branch when the job finishes. + +Because a branch starts from a storage snapshot, the schema and data match the source database at branch time, so migrations run against representative data without touching production. + +# Related {% #related %} + +{% cards %} +{% cards_item href="/docs/products/databases/postgresql/connections" title="Connect" %} +Retrieve credentials, rotate the password, and create scoped connection users. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/connection-pooling" title="Connection pooler" %} +Pool modes, ports, and read/write splitting for serverless workloads. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/branches" title="Branches" %} +Ephemeral database copies for preview environments and CI. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/network-security" title="Network" %} +TLS modes, certificate verification, mTLS, and IP allowlists. +{% /cards_item %} +{% /cards %} diff --git a/src/routes/docs/products/databases/postgresql/integrations/fastapi/+page.markdoc b/src/routes/docs/products/databases/postgresql/integrations/fastapi/+page.markdoc new file mode 100644 index 00000000000..78c582017e5 --- /dev/null +++ b/src/routes/docs/products/databases/postgresql/integrations/fastapi/+page.markdoc @@ -0,0 +1,189 @@ +--- +layout: article +title: FastAPI +description: Use FastAPI and SQLAlchemy 2.x with an Appwrite native PostgreSQL database. Configure the async asyncpg engine, pass TLS through connect_args, inject a session per request, and run Alembic migrations against the direct database port. +--- + +An Appwrite native PostgreSQL database is a standard PostgreSQL engine, so [FastAPI](https://fastapi.tiangolo.com/) with [SQLAlchemy](https://docs.sqlalchemy.org/) and an async driver works against it with no Appwrite-specific configuration. You point `create_async_engine` at the connection string from the [connections](/docs/products/databases/postgresql/connections) page and use the SQLAlchemy ORM, the FastAPI dependency system, and Alembic exactly as you would against any self-hosted PostgreSQL server. + +{% info title="Before you start" %} +You'll need a native PostgreSQL database in a `ready` state and its credentials. See [native PostgreSQL databases](/docs/products/databases/postgresql) to create one and [connections](/docs/products/databases/postgresql/connections) to retrieve the connection string. The primary user is `admin`, and the database name is generated for each database. +{% /info %} + +# Install dependencies {% #install %} + +```bash +pip install "fastapi[standard]" "sqlalchemy[asyncio]" asyncpg alembic +``` + +# Set the connection string {% #connection-string %} + +Copy the connection string from the Console **Credentials** dialog, or fetch it with the [API](/docs/products/databases/postgresql/connections#credentials). Put it in your environment, never commit it. SQLAlchemy's asyncpg dialect uses the `postgresql+asyncpg://` scheme, so swap the leading `postgresql://` for it: + +```env +DATABASE_URL="postgresql+asyncpg://admin:<password>@db-<hash>.<region>.appwrite.center:5432/<database>" +``` + +The string Appwrite returns ends with `?sslmode=require`. Drop that query parameter for asyncpg, asyncpg does not read `sslmode` from the URL. TLS is configured through `connect_args` instead, shown below. + +This guide uses the [asyncpg](https://magicstack.github.io/asyncpg/current/) driver; the same patterns apply to the async `postgresql+psycopg` dialect by changing the URL scheme. + +# Create the async engine {% #engine %} + +The edge proxy terminates TLS for every native PostgreSQL database, so encryption is mandatory. asyncpg's `ssl` argument accepts the libpq-style strings (`require`, `verify-ca`, `verify-full`), `True`, or an `ssl.SSLContext`. Pass it through `connect_args`: + +```python +from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine + +engine = create_async_engine( + settings.database_url, + connect_args={"ssl": "require"}, + pool_size=10, + max_overflow=5, + pool_pre_ping=True, +) + +SessionLocal = async_sessionmaker(engine, expire_on_commit=False) +``` + +`ssl="require"` encrypts the connection without validating the certificate chain. For full verification, pass `ssl="verify-full"` instead; the server certificate is signed by a well-known public CA, so validation succeeds against the system trust store without a custom CA bundle, see the [Network](/docs/products/databases/postgresql/network-security) page. + +# Define a model {% #model %} + +```python +from datetime import datetime + +from sqlalchemy import func +from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column + +class Base(DeclarativeBase): + pass + +class User(Base): + __tablename__ = "users" + + id: Mapped[int] = mapped_column(primary_key=True) + email: Mapped[str] = mapped_column(unique=True) + created_at: Mapped[datetime] = mapped_column(server_default=func.now()) +``` + +# Inject a session per request {% #session %} + +FastAPI's dependency system gives each request its own `AsyncSession` and closes it when the request finishes. Define a dependency that yields a session, then annotate path operations with it: + +```python +from typing import Annotated + +from fastapi import Depends, FastAPI +from sqlalchemy import select +from sqlalchemy.ext.asyncio import AsyncSession + +app = FastAPI() + +async def get_session(): + async with SessionLocal() as session: + yield session + +SessionDep = Annotated[AsyncSession, Depends(get_session)] + +@app.post("/users") +async def create_user(email: str, session: SessionDep): + user = User(email=email) + session.add(user) + await session.commit() + await session.refresh(user) + return user + +@app.get("/users") +async def list_users(session: SessionDep): + result = await session.scalars(select(User).order_by(User.created_at.desc())) + return result.all() +``` + +Create the engine once at module scope and reuse it for the whole process, the pool lives inside it. Don't open a new engine per request. + +# Run migrations {% #migrate %} + +Generate Alembic's async scaffold, which opens the connection asynchronously and hands a sync connection to the migration context: + +```bash +alembic init -t async migrations +``` + +Point `target_metadata` at `Base.metadata` in `migrations/env.py`, then autogenerate and apply: + +```bash +alembic revision --autogenerate -m "init" +alembic upgrade head +``` + +Run migrations against the **direct** engine port (`5432`), not the pooler. DDL needs a real session-level connection, and Alembic's async template already uses a `NullPool`, so a fresh connection is opened and closed per run. The primary `admin` user owns the default database and can run schema changes. Narrower [database roles](/docs/products/databases/postgresql/connections#roles) should only receive the privileges your application needs. + +# Pool sizing {% #sizing %} + +A long-running `uvicorn` server holds a SQLAlchemy pool for its lifetime, so connect to the **direct** engine port (`5432`) with a sized pool. Keep `pool_size` × the number of server processes under the connection limit of your [specification](/docs/products/databases/postgresql#specifications), and let `max_overflow` absorb short bursts: + +```python +engine = create_async_engine( + settings.database_url, + connect_args={"ssl": "require"}, + pool_size=10, + max_overflow=5, +) +``` + +When the same app runs on a serverless platform (for example an Appwrite [function](/docs/products/functions)) where each invocation is a fresh instance, that fans out into far more backend connections than the engine allows. Route runtime traffic through the [connection pooler](/docs/products/databases/postgresql/connection-pooling) on port `6432` instead, and size the pool small per instance: + +```env +DATABASE_URL="postgresql+asyncpg://admin:<password>@db-<hash>.<region>.appwrite.center:6432/<database>" +``` + +# Disable prepared statements on the transaction pooler {% #prepared-statements %} + +The pooler defaults to **transaction mode**, which does not keep a backend connection across statements. asyncpg relies on server-side prepared statements, which transaction mode cannot support, so turn the caches off. This needs **two** settings: asyncpg's own `statement_cache_size` in `connect_args` and SQLAlchemy's dialect-level `prepared_statement_cache_size` in the connection URL: + +```env +DATABASE_URL="postgresql+asyncpg://admin:<password>@db-<hash>.<region>.appwrite.center:6432/<database>?prepared_statement_cache_size=0" +``` + +```python +from sqlalchemy import NullPool + +engine = create_async_engine( + settings.database_url, + connect_args={"ssl": "require", "statement_cache_size": 0}, + poolclass=NullPool, +) +``` + +`statement_cache_size=0` disables asyncpg's prepared statement cache, and `prepared_statement_cache_size=0` disables the dialect's own per-connection statement cache. Use `NullPool` so SQLAlchemy doesn't keep its own pool on top of the pooler's. + +If your application relies on prepared statements, advisory locks, `LISTEN`/`NOTIFY`, or temporary tables, switch the pooler to **session mode** instead and keep statement caching on, see the [pooler](/docs/products/databases/postgresql/connection-pooling#modes) page for the trade-offs. + +# Use a branch for previews and CI {% #branches %} + +[Branches](/docs/products/databases/postgresql/branches) are instant, isolated copies of a database with their own hostname and connection string. They're ideal for running migrations against throwaway data in a pull-request preview or an integration-test job: + +1. Create a branch from the API and read its `connectionString`. +2. Rewrite the scheme to `postgresql+asyncpg://` and export it as `DATABASE_URL`. +3. Run `alembic upgrade head` against the branch's direct port, then your test suite. +4. Delete the branch when the job finishes. + +Because a branch starts from a storage snapshot, the schema and data match the source database at branch time, so migrations run against realistic data without touching production. + +# Related {% #related %} + +{% cards %} +{% cards_item href="/docs/products/databases/postgresql/connections" title="Connections" %} +Retrieve credentials, rotate the password, and create scoped database roles. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/connection-pooling" title="Connection pooler" %} +Pool modes, ports, and read/write splitting for serverless workloads. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/branches" title="Branches" %} +Ephemeral database copies for preview environments and CI. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/network-security" title="Network" %} +TLS modes, certificate verification, mTLS, and IP allowlists. +{% /cards_item %} +{% /cards %} diff --git a/src/routes/docs/products/databases/postgresql/integrations/gorm/+page.markdoc b/src/routes/docs/products/databases/postgresql/integrations/gorm/+page.markdoc new file mode 100644 index 00000000000..c2c31d100a3 --- /dev/null +++ b/src/routes/docs/products/databases/postgresql/integrations/gorm/+page.markdoc @@ -0,0 +1,168 @@ +--- +layout: article +title: GORM +description: Use GORM with an Appwrite native PostgreSQL database in Go. Build the DSN, open a connection, size the database/sql pool against the direct connection, and run migrations with AutoMigrate or golang-migrate. +--- + +A native PostgreSQL database is a standard PostgreSQL engine, so [GORM](https://gorm.io/) talks to it with no Appwrite-specific configuration. You build a connection string from the credentials in the Console, hand it to the GORM PostgreSQL driver, and use models, `AutoMigrate`, and the query API exactly as you would against any self-hosted PostgreSQL server. + +{% info title="Before you start" %} +You'll need a native PostgreSQL database in a `ready` state and its credentials. See [PostgreSQL databases](/docs/products/databases/postgresql) to create one. To retrieve the hostname, password, database name, and connection string, open the database in the Console and click **Credentials**. The **Credentials** page includes **Details**, **DSN**, **.env**, **Prisma**, **Drizzle**, and **psql** tabs. The primary user is `admin`, and Appwrite generates the database name for each database. +{% /info %} + +# Build the DSN {% #dsn %} + +The edge proxy terminates TLS for every native PostgreSQL database, so no certificate file is needed. Keep the password out of source and read the connection details from the environment: + +```env +DB_HOST="db-<hash>.<region>.appwrite.center" +DB_NAME="<database>" +DB_PASSWORD="<password>" +``` + +GORM's PostgreSQL driver accepts the pgx key/value DSN. Set `sslmode=require`: + +```go +dsn := fmt.Sprintf( + "host=%s user=admin password=%s dbname=%s port=5432 sslmode=require", + os.Getenv("DB_HOST"), os.Getenv("DB_PASSWORD"), os.Getenv("DB_NAME"), +) +``` + +The URL form from the **DSN** tab works too, and the driver parses either format: `postgresql://admin:<password>@db-<hash>.<region>.appwrite.center:5432/<database>?sslmode=require`. For full certificate verification, add `sslmode=verify-full`, no CA file needed: Go's drivers validate against the system certificate pool, and the proxy's certificate is signed by a public CA. + +For mTLS, see the [Network](/docs/products/databases/postgresql/network-security) page. + +# Open a connection {% #open %} + +Pass the DSN to the driver's `Open` function and call `gorm.Open`: + +```go +package main + +import ( + "fmt" + "os" + + "gorm.io/driver/postgres" + "gorm.io/gorm" +) + +func main() { + dsn := fmt.Sprintf( + "host=%s user=admin password=%s dbname=%s port=5432 sslmode=require", + os.Getenv("DB_HOST"), os.Getenv("DB_PASSWORD"), os.Getenv("DB_NAME"), + ) + + db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{}) + if err != nil { + panic(err) + } + + _ = db +} +``` + +Connect to the **direct** engine port (`5432`) for a long-running server, see [pool sizing](#pool) below. If you route through the [connection pooler](/docs/products/databases/postgresql/connection-pooling) in its default transaction mode, use `postgres.New` with `PreferSimpleProtocol: true` so the driver stops issuing implicit prepared statements, which transaction mode cannot keep across statements: + +```go +db, err := gorm.Open(postgres.New(postgres.Config{ + DSN: dsn, // pooler host, port 6432 + PreferSimpleProtocol: true, +}), &gorm.Config{}) +``` + +# Define a model and migrate {% #model %} + +Declare your models as Go structs and let GORM create the tables with `AutoMigrate`: + +```go +type User struct { + ID uint `gorm:"primaryKey"` + Email string `gorm:"uniqueIndex"` + CreatedAt time.Time +} + +if err := db.AutoMigrate(&User{}); err != nil { + panic(err) +} +``` + +`AutoMigrate` creates the table if it's missing and adds any missing columns and indexes. It does not drop columns or change existing column types, so it's convenient in development but not a substitute for versioned migrations in production. Either way, run schema changes against the **direct** engine port: DDL needs a real session connection, and the primary `admin` user owns the generated database. Scoped connection users (`readonly` / `readwrite`) intentionally cannot run DDL. + +For versioned migrations, [golang-migrate](https://github.com/golang-migrate/migrate) runs ordered up/down files. Point it at the direct engine port: + +```bash +migrate -path ./migrations \ + -database "postgresql://admin:$DB_PASSWORD@$DB_HOST:5432/$DB_NAME?sslmode=require" \ + up +``` + +# Size the connection pool {% #pool %} + +GORM manages a `database/sql` pool under the hood. A long-running Go server holds that pool for its whole lifetime, so connect to the **direct** engine port and cap the pool yourself against the engine's connection limit. Reach the underlying `*sql.DB` with `db.DB()`: + +```go +sqlDB, err := db.DB() +if err != nil { + panic(err) +} + +sqlDB.SetMaxOpenConns(25) +sqlDB.SetMaxIdleConns(25) +sqlDB.SetConnMaxLifetime(time.Hour) +``` + +Keep the sum of `SetMaxOpenConns` across every instance below the specification's `maxConnections`. If you run many instances or a serverless/edge runtime that opens a fresh pool per invocation, route through the [connection pooler](/docs/products/databases/postgresql/connection-pooling) and keep each instance's pool small. The pooler multiplexes them onto a handful of backend connections. + +# Use sqlx instead {% #sqlx %} + +If you prefer raw SQL with light struct scanning, [sqlx](https://github.com/jmoiron/sqlx) wraps `database/sql` and uses the same DSN. + +Register the `pgx` stdlib driver (or `lib/pq`) and connect: + +```go +import ( + _ "github.com/jackc/pgx/v5/stdlib" + "github.com/jmoiron/sqlx" +) + +db, err := sqlx.Connect("pgx", + fmt.Sprintf("host=%s user=admin password=%s dbname=%s port=5432 sslmode=require", + os.Getenv("DB_HOST"), os.Getenv("DB_PASSWORD"), os.Getenv("DB_NAME"))) +if err != nil { + panic(err) +} + +db.SetMaxOpenConns(25) +``` + +The same pooler caveat applies: in transaction mode, disable implicit prepared statements (the pgx stdlib driver exposes a simple-protocol option, and `lib/pq` can be told to skip prepares), or use [session mode](/docs/products/databases/postgresql/connection-pooling#modes). `sslmode=require` needs no CA file, and neither does `verify-full`: Go's drivers fall back to the system certificate pool when `sslrootcert` is unset, and the proxy's certificate is signed by a public CA that pool already trusts. Set `sslrootcert` only when the container image ships without CA certificates. + +# Use a branch for previews and CI {% #branches %} + +[Branches](/docs/products/databases/postgresql/branches) are instant, isolated copies of a database with their own hostname and connection string, ideal for running migrations against throwaway data in a pull-request preview or an integration-test job: + +1. Create a branch from the API and read its `connectionString`. +2. Export the host and password into the environment your tests read. +3. Run `migrate ... up` (or `AutoMigrate`) and your test suite against the branch's direct port. +4. Delete the branch when the job finishes. + +Because a branch starts from a storage snapshot, the schema and data match the source database at branch time, so migrations run against realistic data without touching production. + +# Related {% #related %} + +{% cards %} +{% cards_item href="/docs/products/databases/postgresql/connections" title="Connect" %} +Retrieve credentials, rotate the password, and create scoped connection users. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/connection-pooling" title="Connection pooler" %} +Pool modes, ports, and read/write splitting for serverless workloads. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/branches" title="Branches" %} +Ephemeral database copies for preview environments and CI. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/network-security" title="Network" %} +TLS modes, certificate verification, mTLS, and IP allowlists. +{% /cards_item %} +{% /cards %} diff --git a/src/routes/docs/products/databases/postgresql/integrations/grafana/+page.markdoc b/src/routes/docs/products/databases/postgresql/integrations/grafana/+page.markdoc new file mode 100644 index 00000000000..b243e714a9d --- /dev/null +++ b/src/routes/docs/products/databases/postgresql/integrations/grafana/+page.markdoc @@ -0,0 +1,105 @@ +--- +layout: article +title: Grafana +description: Connect Grafana to an Appwrite native PostgreSQL database as a data source and build dashboards. Create a read-only reporting role, configure the PostgreSQL data source with TLS, and provision it from YAML. +--- + +An Appwrite [native PostgreSQL database](/docs/products/databases/postgresql) exposes a standard managed PostgreSQL 18 or 17 engine, so [Grafana](https://grafana.com/) connects to it through the built-in **PostgreSQL data source** with no Appwrite-specific configuration. Point the data source at your database hostname, authenticate with a read-only reporting role, and query your tables to build dashboards and alerts. + +{% info title="Before you start" %} +You'll need a native PostgreSQL database in a `ready` state and its credentials. In the Console, open the database and click **Credentials**. Use the **Details** tab for individual values, or copy a ready-made string from the **DSN**, **.env**, **Prisma**, **Drizzle**, or **psql** tab. You can also call `postgresql.get()` from the Appwrite API to read `hostname`, `connectionUser`, `connectionPassword`, and `connectionString`. The primary user is `admin`, and Appwrite generates the database name for each database. +{% /info %} + +# Create a reporting role {% #reporting-role %} + +Dashboards should not connect as the primary `admin` user, which owns the database and can run schema changes. Create a PostgreSQL role for Grafana from the **Roles** tab of your database in the Console, then grant it the `SELECT` privileges your dashboards need from the SQL editor or `psql`. + +Use that role's name and password in the Grafana data source below. For more about retrieving credentials, rotating the primary password, and managing database roles, see [Connections](/docs/products/databases/postgresql/connections). + +# Choose a connection target {% #target %} + +Grafana holds its data source connections open for the lifetime of the process. Long-lived connections should use either the direct PostgreSQL port `5432` or a [connection pooler](/docs/products/databases/postgresql/connection-pooling) running in **session mode**. + +Do not point Grafana at the **transaction-mode** pooler. Transaction mode hands a backend connection back to the pool after every statement, which breaks the session assumptions Grafana relies on for connection reuse and prepared statements. For a typical dashboard workload the direct PostgreSQL port is the simplest choice. See the [pooler modes](/docs/products/databases/postgresql/connection-pooling#modes) page for the trade-offs. + +# Add the PostgreSQL data source {% #data-source %} + +In Grafana, open **Connections** > **Data sources** > **Add data source** and select **PostgreSQL**. Fill in the connection details using the values from your native PostgreSQL database: + +| Field | Value | +| --- | --- | +| **Host URL** | `db-<hash>.<region>.appwrite.center:5432` | +| **Database name** | `<database>` | +| **Username** | `grafana_ro` | +| **Password** | the password for the reporting role | +| **TLS/SSL Mode** | `require` | +| **Version** | PostgreSQL 10+; Grafana auto-detects the server version on save when it can connect | + +Regions are `fra`, `nyc`, `sfo`, `sgp`, `syd`, and `tor`. The edge proxy terminates TLS for every native PostgreSQL database, so **TLS/SSL Mode** `require` works with no certificate upload. + +If you use Grafana Cloud and restrict database access with an IP allowlist, add the Grafana Cloud outbound IP ranges for your stack to the database allowlist. Grafana Cloud can reach the public Appwrite database hostname directly. Private connectivity features are only needed when the database is on a private network. + +Under **Connection limits**, keep the connection counts modest so Grafana doesn't exhaust the engine's connection budget. **Max open** caps total connections from this Grafana instance, **Max idle** caps pooled idle connections, and **Max lifetime** recycles connections after the given number of seconds. Select **Save & test** to verify connectivity. + +# Provision from YAML {% #provisioning %} + +Instead of configuring the data source by hand, you can [provision](https://grafana.com/docs/grafana/latest/administration/provisioning/) it declaratively. Drop a file into Grafana's `provisioning/datasources/` directory and read the password from an environment variable so it never lands in source control: + +```yaml +apiVersion: 1 + +datasources: + - name: Appwrite native PostgreSQL + type: postgres + url: db-<hash>.<region>.appwrite.center:5432 + user: grafana_ro + jsonData: + database: <database> + sslmode: require + postgresVersion: 1500 + maxOpenConns: 5 + maxIdleConns: 2 + maxIdleConnsAuto: true + connMaxLifetime: 14400 + secureJsonData: + password: $GRAFANA_DB_PASSWORD + editable: false +``` + +`postgresVersion` takes Grafana's encoded version values (`1500` for PostgreSQL 15, currently the highest option), so pick the highest value available for a native PostgreSQL database. The `database` key lives under `jsonData` in current Grafana releases, and Grafana expands `$GRAFANA_DB_PASSWORD` from the process environment when it loads the provisioning file. See the [PostgreSQL data source](https://grafana.com/docs/grafana/latest/datasources/postgres/configure/) docs for every available field. + +# Build a panel {% #panel %} + +With the data source connected, create a dashboard and add a panel backed by it. Switch the query editor to code mode and write a read-only query against your tables. For example, to plot daily sign-ups from a `users` table over time: + +```text +SELECT + date_trunc('day', created_at) AS time, + count(*) AS signups +FROM users +GROUP BY 1 +ORDER BY 1 +``` + +Grafana maps the `time` column to the panel's time axis and `signups` to the value. Because the data source authenticates as a read-only reporting role, any query that attempts to write fails at the database, which keeps a misconfigured panel from mutating production data. + +# Related {% #related %} + +{% cards %} +{% cards_item href="/docs/products/databases/postgresql" title="PostgreSQL databases" %} +Overview of native PostgreSQL database engines, versions, and regions. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/connections" title="Connect" %} +Retrieve credentials, rotate the password, and manage database roles. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/connection-pooling" title="Connection pooler" %} +Pool modes and ports. Use the direct PostgreSQL port or session mode for Grafana. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/network-security" title="Network" %} +TLS modes, certificate verification, and IP allowlists. +{% /cards_item %} +{% /cards %} + +{% arrow_link href="/docs/products/databases/postgresql/connections" %} +Connect to a native PostgreSQL database +{% /arrow_link %} diff --git a/src/routes/docs/products/databases/postgresql/integrations/laravel/+page.markdoc b/src/routes/docs/products/databases/postgresql/integrations/laravel/+page.markdoc new file mode 100644 index 00000000000..7d3075b20a7 --- /dev/null +++ b/src/routes/docs/products/databases/postgresql/integrations/laravel/+page.markdoc @@ -0,0 +1,204 @@ +--- +layout: article +title: Laravel +description: Use Laravel and Eloquent with an Appwrite native PostgreSQL database. Configure the connection, run migrations against the direct port, and pool serverless traffic through the connection pooler. +--- + +A native PostgreSQL database is a standard PostgreSQL engine, so [Laravel](https://laravel.com/docs) works against it with no Appwrite-specific configuration. Point the `pgsql` connection in `config/database.php` at the credentials from the [Connections](/docs/products/databases/postgresql/connections) page, then use Eloquent, the query builder, migrations, and queues as you would against any PostgreSQL server. + +{% info title="Before you start" %} +You'll need a native PostgreSQL database in a `ready` state and its credentials. See [PostgreSQL databases](/docs/products/databases/postgresql) to create one. To retrieve credentials, open the database in the Console, click **Credentials**, and use the **Details**, **DSN**, **.env**, **Prisma**, **Drizzle**, or **psql** tab. The primary username is `admin`, and the database name is generated per database. +{% /info %} + +# Configure the connection {% #connection %} + +Laravel reads database credentials from `.env`. Copy the values from the Console credentials dialog, or fetch them with [`postgresql.get()`](/docs/products/databases/postgresql/connections#credentials), and set the matching connection. Never commit `.env`: + +```env +DB_CONNECTION=pgsql +DB_HOST=db-<hash>.<region>.appwrite.center +DB_PORT=5432 +DB_DATABASE=<database> +DB_USERNAME=admin +DB_PASSWORD=<password> +DB_SSLMODE=require +``` + +The scaffolded `config/database.php` wires these variables into the `pgsql` connection, including SSL: + +```php +'pgsql' => [ + 'driver' => 'pgsql', + 'url' => env('DB_URL'), + 'host' => env('DB_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', '5432'), + 'database' => env('DB_DATABASE', 'laravel'), + 'username' => env('DB_USERNAME', 'root'), + 'password' => env('DB_PASSWORD', ''), + 'charset' => env('DB_CHARSET', 'utf8'), + 'prefix' => '', + 'prefix_indexes' => true, + 'search_path' => 'public', + 'sslmode' => env('DB_SSLMODE', 'prefer'), +], +``` + +`sslmode` is a top-level key on the PostgreSQL connection. Setting `DB_SSLMODE=require` matches the `sslmode=require` that Appwrite uses. Appwrite Cloud terminates TLS for every native PostgreSQL database, so certificate files are not needed for `require`. For full certificate verification, set `DB_SSLMODE=verify-full` and point `sslrootcert` at a trusted root store, `system` on libpq 16+, or your OS bundle such as `/etc/ssl/certs/ca-certificates.crt`. The proxy certificate is signed by a public CA, so there is no Appwrite-specific CA to download: + +```php +'sslmode' => env('DB_SSLMODE', 'prefer'), +'sslrootcert' => env('DB_SSLROOTCERT'), +``` + +# Run migrations {% #migrate %} + +Define your schema with a migration: + +```php +Schema::create('posts', function (Blueprint $table) { + $table->id(); + $table->string('title'); + $table->text('body'); + $table->timestamps(); +}); +``` + +Apply migrations from your machine or a deploy step: + +```bash +php artisan migrate + +# non-interactive, for CI and production deploys +php artisan migrate --force +``` + +Run `migrate` against the **direct** PostgreSQL port (`5432`), not the pooler. Migrations issue DDL that needs a session-level connection, and the transaction-mode pooler can't keep state across statements. The primary `admin` user owns the default database and can run schema changes. Narrower [connection users](/docs/products/databases/postgresql/connections#roles), such as read-only reporting roles, should not run DDL. + +# Query with Eloquent {% #query %} + +Once the schema is migrated, use Eloquent models and the query builder as usual: + +```php +namespace App\Models; + +use Illuminate\Database\Eloquent\Model; + +class Post extends Model +{ + protected $fillable = [ + 'title', + 'body', + ]; +} +``` + +```php +use App\Models\Post; + +$post = Post::create([ + 'title' => 'Hello from a native PostgreSQL database', + 'body' => 'Stored in a native PostgreSQL database.', +]); + +$recent = Post::query() + ->orderByDesc('created_at') + ->limit(10) + ->get(); +``` + +Nothing about the native PostgreSQL database changes how Eloquent, relationships, transactions, or the query builder behave. It is a standard PostgreSQL server behind a TLS connection. + +# Pool connections from serverless {% #pooling %} + +The right port depends on how your app runs. + +A **long-running** PHP process, traditional PHP-FPM with persistent connections, [Laravel Octane](https://laravel.com/docs/octane), or a queue worker, holds its own backend connection for its lifetime. Point these at the **direct** PostgreSQL port (`5432`), or at the [connection pooler](/docs/products/databases/postgresql/connection-pooling) in **session mode**. Don't put a long-lived process behind the transaction-mode pooler. + +A **serverless** or per-request deployment (Vercel, AWS Lambda, Cloud Run) opens a fresh connection on every invocation and fans out into far more backend connections than the engine allows. Route that traffic through the pooler's **transaction-mode** port (`6432`) on the same hostname, and give Laravel direct connection details for migrations and other schema operations: + +```env +# Runtime: pooled, transaction mode +DB_HOST=db-<hash>.<region>.appwrite.center +DB_PORT=6432 +DB_DATABASE=<database> +DB_USERNAME=admin +DB_PASSWORD=<password> +DB_POOLED=true + +# Migrations and schema operations: direct PostgreSQL port +DB_DIRECT_HOST=db-<hash>.<region>.appwrite.center +DB_DIRECT_PORT=5432 +DB_DIRECT_USERNAME=admin +DB_DIRECT_PASSWORD=<password> +DB_DIRECT_SSLMODE=require +``` + +Extend the `pgsql` connection in `config/database.php` with Laravel's pooled connection keys: + +```php +'pgsql' => [ + 'driver' => 'pgsql', + 'url' => env('DB_URL'), + 'host' => env('DB_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', '5432'), + 'database' => env('DB_DATABASE', 'laravel'), + 'username' => env('DB_USERNAME', 'root'), + 'password' => env('DB_PASSWORD', ''), + 'charset' => env('DB_CHARSET', 'utf8'), + 'prefix' => '', + 'prefix_indexes' => true, + 'search_path' => 'public', + 'sslmode' => env('DB_SSLMODE', 'prefer'), + 'pooled' => env('DB_POOLED', false), + 'direct' => array_filter([ + 'host' => env('DB_DIRECT_HOST'), + 'port' => env('DB_DIRECT_PORT'), + 'username' => env('DB_DIRECT_USERNAME'), + 'password' => env('DB_DIRECT_PASSWORD'), + 'sslmode' => env('DB_DIRECT_SSLMODE'), + ]), +], +``` + +Laravel uses the direct connection for migrations, schema dumps, restores, and database inspection commands when pooled mode is enabled. You can also call `DB::connection('pgsql::direct')` for schema operations that need the direct port. The transaction-mode pooler does not keep a backend connection across statements, so server-side prepared statements, advisory locks, `LISTEN`/`NOTIFY`, and `SET LOCAL` are unavailable. If your app relies on those, use **session mode**. See the [pooler](/docs/products/databases/postgresql/connection-pooling#modes) page for the trade-offs. + +# Queues and Horizon {% #queues %} + +A queue worker is a long-running process. `php artisan queue:work` boots once and processes jobs for its whole lifetime, holding a persistent database connection the entire time. The same applies to every worker that [Laravel Horizon](https://laravel.com/docs/horizon) supervises. Treat workers like any other long-lived process: + +- Connect them to the **direct** PostgreSQL port (`5432`) or the **session-mode** pooler, never the transaction-mode pooler. +- Restart workers periodically with `--max-time` or `--max-jobs` so a fresh process reclaims memory and reopens its connection. Supervisor or Horizon restarts them automatically. + +```bash +php artisan queue:work --max-time=3600 --max-jobs=500 +``` + +Each worker counts as one backend connection, so size your worker pool (and Horizon's `maxProcesses`) against the connection budget of your [specification](/docs/products/databases/postgresql). Horizon itself requires Redis for the queue backend; only your application's data connection touches the native PostgreSQL database. + +# Use a branch for previews and CI {% #branches %} + +PostgreSQL [branches](/docs/products/databases/postgresql/branches) are instant, isolated copies of a database with their own hostname. Create them from the API for running migrations against throwaway data in a pull-request preview or an integration-test job: + +1. Create a branch from the API and read its connection details. +2. Export them as the `DB_*` variables for the job. +3. Run `php artisan migrate --force` and your test suite against the branch. +4. Delete the branch when the job finishes. + +Because a branch starts from a storage snapshot, the schema and data match the source database at branch time, so migrations and tests run against realistic data without touching production. + +# Related {% #related %} + +{% cards %} +{% cards_item href="/docs/products/databases/postgresql/connections" title="Connect" %} +Retrieve credentials, rotate the password, and create scoped connection users. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/connection-pooling" title="Connection pooler" %} +Pool modes, ports, and read/write splitting for serverless workloads. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/branches" title="Branches" %} +Ephemeral database copies for preview environments and CI. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/network-security" title="Network" %} +TLS modes, certificate verification, mTLS, and IP allowlists. +{% /cards_item %} +{% /cards %} diff --git a/src/routes/docs/products/databases/postgresql/integrations/metabase/+page.markdoc b/src/routes/docs/products/databases/postgresql/integrations/metabase/+page.markdoc new file mode 100644 index 00000000000..6a85f4d58eb --- /dev/null +++ b/src/routes/docs/products/databases/postgresql/integrations/metabase/+page.markdoc @@ -0,0 +1,80 @@ +--- +layout: article +title: Metabase +description: Connect Metabase to an Appwrite native PostgreSQL database for analytics. Use a read-only PostgreSQL role, configure SSL, and build dashboards on a session-safe connection. +--- + +Appwrite's native PostgreSQL database is a standard PostgreSQL engine, so [Metabase](https://www.metabase.com/) can connect to it without an Appwrite-specific adapter. Add the database in Metabase, point it at the host from the [Connections](/docs/products/databases/postgresql/connections) page, and Metabase will sync the schema so your team can build questions and dashboards. + +{% info title="Before you start" %} +You'll need a native PostgreSQL database in a `ready` state and its credentials. In the Console, open the database and click **Credentials**. Copy the individual values from the **Details** tab, or use the **DSN**, **.env**, or **psql** tab. You can also fetch the same values with [`postgresql.get()`](/docs/products/databases/postgresql/connections#credentials). The primary user is `admin`, and the database name is generated per database. +{% /info %} + +# Use a read-only PostgreSQL role {% #read-only-role %} + +Dashboards should not connect as the primary `admin` user. That role owns the database and can run schema changes. For analytics, create a read-only PostgreSQL role for Metabase from the database **Roles** tab in the Console, then grant it access only to the schemas and tables Metabase should query. + +At minimum, a reporting role needs permission to connect to the database, usage on the schemas you want to expose, and `SELECT` on the tables and views in those schemas. Use the [SQL editor](/docs/products/databases/postgresql/quick-start#first-queries), `psql`, or your migration workflow to apply the grants after you create the role. See [Database roles](/docs/products/databases/postgresql/connections#roles) for how roles work with native PostgreSQL databases. + +If you plan to use Metabase features that write data, such as editable table data, use a separate connection with the specific write privileges that feature needs. Keep the analytics connection read-only. + +# Add the database in Metabase {% #add-database %} + +In Metabase, click the grid icon, then open **Admin > Databases > Add a database**. Choose **PostgreSQL** as the database type and fill in the connection form with the values from the [Connections](/docs/products/databases/postgresql/connections) page. + +| Field | Value | +|-------|-------| +| Host | `db-<hash>.<region>.appwrite.center` | +| Port | `5432` | +| Database name | `<database>` | +| Username | your read-only PostgreSQL role | +| Password | the role password | + +Turn on **Use a secure connection (SSL)** and set **SSL Mode** to `require`. Appwrite Cloud requires TLS for native PostgreSQL connections. If you choose `verify-ca` or `verify-full`, Metabase also requires a root certificate in PEM format. See [Network security](/docs/products/databases/postgresql/network-security) for Appwrite TLS and network controls. + +{% info title="Use a session-safe connection" %} +Metabase keeps database sessions open and can use session-level PostgreSQL behavior while exploring data. Connect it to the direct PostgreSQL port (`5432`) or to the [connection pooler](/docs/products/databases/postgresql/connection-pooling) in `session` mode. Transaction-mode pooling can break session-level features because a client session is not bound to one backend connection. +{% /info %} + +Click **Save changes**. Metabase verifies the connection and starts its first schema sync. + +# Build a question or dashboard {% #build %} + +Once the first sync finishes, your tables appear in the data picker. To build your first chart: + +1. Click **+ New > Question** and pick your Appwrite PostgreSQL database as the data source. +2. Choose a table, add a summary such as count, sum, or average, and group by a column such as a timestamp. +3. Switch the visualization to a line, bar, or table view, then save the question. +4. Add saved questions to a dashboard and use filters to slice data across cards. + +Because the analytics connection is read-only, native SQL questions can inspect data without changing it. Queries that attempt writes will fail unless you intentionally connect Metabase with a role that has write privileges. + +# How Metabase syncs your schema {% #sync %} + +After you connect, Metabase scans the database to discover tables, columns, constraints, and field metadata, then keeps that metadata current on a schedule: + +- A lightweight schema sync runs hourly by default. +- A more intensive field-value scan runs daily by default to populate filter dropdowns. + +New tables and columns appear after the next sync. To pull them in immediately, open **Admin > Databases > your database** and click **Sync database schema**. You can also restrict which schemas Metabase tracks and adjust the sync and scan cadence from the database settings. Refer to the [Metabase documentation](https://www.metabase.com/docs/latest/databases/sync-scan) for the full set of sync and scan options. + +# Use a branch for testing {% #branches %} + +[Branches](/docs/products/databases/postgresql/branches) are isolated copies of a native PostgreSQL database with their own host and credentials. Point a second Metabase database connection at a branch when you want to validate a dashboard against a snapshot of production data without querying the live database. Branches are managed through the API, and you can delete the branch when testing is complete. + +# Related {% #related %} + +{% cards %} +{% cards_item href="/docs/products/databases/postgresql" title="PostgreSQL" %} +Provision and manage a native PostgreSQL database for your project. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/connections" title="Connections" %} +Retrieve credentials, rotate the primary password, and manage PostgreSQL roles. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/connection-pooling" title="Connection pooling" %} +Pool modes and ports, including why BI tools need session or direct connections. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/network-security" title="Network security" %} +TLS, certificate verification, IP allowlists, and idle connection timeouts. +{% /cards_item %} +{% /cards %} diff --git a/src/routes/docs/products/databases/postgresql/integrations/nextjs/+page.markdoc b/src/routes/docs/products/databases/postgresql/integrations/nextjs/+page.markdoc new file mode 100644 index 00000000000..ede902ded10 --- /dev/null +++ b/src/routes/docs/products/databases/postgresql/integrations/nextjs/+page.markdoc @@ -0,0 +1,150 @@ +--- +layout: article +title: Next.js +description: Connect a Next.js App Router application to an Appwrite native PostgreSQL database from Route Handlers, Server Actions, and Server Components, pool from serverless, and fall back to the SQL API on the Edge runtime. +--- + +An Appwrite native PostgreSQL database works with standard PostgreSQL drivers and ORMs, so a [Next.js](https://nextjs.org/) App Router application can query it from server-side code. Point your driver at the connection string from the [Connections](/docs/products/databases/postgresql/connections) page and keep all database access on the server. + +{% info title="Before you start" %} +You'll need a native PostgreSQL database in a `ready` state and its credentials. See [PostgreSQL](/docs/products/databases/postgresql) to create one and [Connections](/docs/products/databases/postgresql/connections) to retrieve the connection string. The primary user is `admin`, and Appwrite generates the database name for each database. +{% /info %} + +# Where to connect {% #where %} + +In the App Router, every server-side execution context runs on the **Node.js runtime by default**, and the Node.js runtime can open raw TCP sockets. That means you can use a standard database driver from any of these: + +- **Route Handlers** (`app/api/.../route.ts`) for public endpoints, webhooks, and REST-style APIs. +- **Server Actions** (`'use server'` functions) for form submissions and app-internal mutations. +- **Server Components** (`async` components) for read queries that render straight into the page. + +Never import a database driver into a Client Component (`'use client'`) or ship the connection string to the browser. Keep all database access on the server. + +The one exception is the **Edge runtime** (`export const runtime = 'edge'`), which runs on a constrained environment that **cannot open TCP database sockets**. If a route opts into Edge, use the [SQL API](/docs/products/databases/postgresql/quick-start#first-queries) over HTTPS instead, see [the Edge runtime section](#edge) below. + +# Environment variables {% #env %} + +Put the connection string in your environment and never commit it. For local development, use `.env.local` (Next.js loads it automatically and it's git-ignored by default): + +```env +DATABASE_URL="postgresql://admin:<password>@db-<hash>.<region>.appwrite.center:6432/<database>?sslmode=require" +DIRECT_URL="postgresql://admin:<password>@db-<hash>.<region>.appwrite.center:5432/<database>?sslmode=require" +``` + +`DATABASE_URL` points at the [connection pooler](/docs/products/databases/postgresql/connection-pooling) port (`6432`) for runtime traffic, and `DIRECT_URL` points at the PostgreSQL engine port (`5432`) for migrations. The next section explains why. The `sslmode=require` parameter is already part of the string Appwrite returns, so no extra certificate configuration is needed. For full verification (`verify-full`) or mTLS, see the [Network security](/docs/products/databases/postgresql/network-security) page. + +# Pool serverless connections {% #pooling %} + +When you deploy to Vercel, Netlify, or any serverless platform, each invocation can spin up a fresh instance with its own connection pool. Hundreds of concurrent invocations fan out into far more backend connections than the engine allows. Route runtime traffic through the [connection pooler](/docs/products/databases/postgresql/connection-pooling) on the pooler port so it can multiplex those instances over a small number of backend connections. + +The pooler defaults to **transaction mode**, which does not keep a backend connection across statements, so server-side prepared statements aren't available. Reserve the engine port for migrations, which need a session-level connection. The two-URL split above (`DATABASE_URL` pooled, `DIRECT_URL` direct) is exactly what an ORM like Prisma expects. + +# Use a singleton client {% #singleton %} + +Instantiate one client per module scope and reuse it across invocations, so warm serverless instances don't reconnect on every request. In development, Next.js hot-reload re-evaluates modules, which can leak connections, so cache the client on `globalThis`. + +With [postgres.js](https://github.com/porsager/postgres) (note `prepare: false` for transaction-mode pooling): + +```ts +// lib/db.ts +import postgres from 'postgres'; + +const globalForDb = globalThis as unknown as { sql?: ReturnType<typeof postgres> }; + +export const sql = + globalForDb.sql ?? + postgres(process.env.DATABASE_URL!, { + prepare: false, // required: pooler transaction mode has no server-side prepared statements + }); + +if (process.env.NODE_ENV !== 'production') globalForDb.sql = sql; +``` + +Query it from a Server Component or Route Handler: + +```ts +// app/users/route.ts +import { sql } from '@/lib/db'; + +export async function GET() { + const users = await sql`SELECT id, email FROM users ORDER BY created_at DESC LIMIT 10`; + return Response.json(users); +} +``` + +# Use Prisma or Drizzle {% #orm %} + +For a typed schema, migrations, and a query builder, reach for an ORM. Both integrate with the pooled `DATABASE_URL` plus direct `DIRECT_URL` pattern above. + +- **Prisma**: point the runtime at the pooled connection string and keep the Prisma CLI on the engine port for migrations, then run `prisma migrate deploy`. See the [Prisma](/docs/products/databases/postgresql/integrations/prisma) guide for the full config and migration flow. +- **Drizzle**: use a pooled client (`prepare: false` on postgres.js) for runtime and the direct URL for `drizzle-kit` migrations. See the [Drizzle](/docs/products/databases/postgresql/integrations/drizzle) guide. + +{% arrow_link href="/docs/products/databases/postgresql/integrations/prisma" %} +Set up Prisma against native PostgreSQL +{% /arrow_link %} + +# Edge runtime: use the SQL API {% #edge %} + +If a Route Handler or route segment opts into the Edge runtime, it can't open a TCP socket, so no engine driver will work there: + +```ts +export const runtime = 'edge'; // no TCP sockets available +``` + +From the Edge runtime, you can execute one parameterised SQL statement over HTTPS and get JSON back. `SELECT`, `INSERT`, `UPDATE`, and `DELETE` statements are allowed by default. Use the global `fetch` available in the Edge runtime: + +```ts +// app/edge-users/route.ts +export const runtime = 'edge'; + +export async function GET() { + const response = await fetch( + 'https://<REGION>.cloud.appwrite.io/v1/postgresql/<DATABASE_ID>/executions', + { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-Appwrite-Project': process.env.APPWRITE_PROJECT_ID!, + 'X-Appwrite-Key': process.env.APPWRITE_API_KEY!, + }, + body: JSON.stringify({ + sql: 'SELECT id, email FROM users WHERE created_at > $1 ORDER BY created_at DESC LIMIT $2', + bindings: ['2026-05-01T00:00:00Z', 10], + }), + }, + ); + + const { rows } = await response.json(); + return Response.json(rows); +} +``` + +The response is `{ rows, rowCount, columns, durationMs, truncated, bytes }`. Bindings are sent separately and never interpolated into the SQL string. Add `APPWRITE_PROJECT_ID` and `APPWRITE_API_KEY` (a key with the `databases.read` scope) to your environment alongside the database URLs. + +{% arrow_link href="/docs/products/databases/postgresql/quick-start#first-queries" %} +Read the SQL API reference +{% /arrow_link %} + +# Local development {% #local %} + +`next dev` runs on the Node.js runtime, so a local server connects to the native PostgreSQL database over TLS exactly like production. Keep `DATABASE_URL` and `DIRECT_URL` in `.env.local`. + +For throwaway data in tests or experiments, create a [branch](/docs/products/databases/postgresql/branches), an instant, isolated copy with its own connection string, and point `.env.local` at it. Delete the branch when you're done. + +# Deploy {% #deploy %} + +When you deploy, set the same `DATABASE_URL` (pooled) and `DIRECT_URL` (direct) as environment variables on your hosting platform, run your migrations in the build step, and fall back to the SQL API from any Edge Functions. + +# Related {% #related %} + +{% cards %} +{% cards_item href="/docs/products/databases/postgresql/integrations/prisma" title="Prisma" %} +Datasource config, pooled and direct URLs, and the migration workflow. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/quick-start#first-queries" title="SQL API" %} +Query over HTTPS from the Edge runtime without a TCP connection. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/connection-pooling" title="Connection pooler" %} +Pool modes, ports, and read/write splitting for serverless workloads. +{% /cards_item %} +{% /cards %} diff --git a/src/routes/docs/products/databases/postgresql/integrations/prisma/+page.markdoc b/src/routes/docs/products/databases/postgresql/integrations/prisma/+page.markdoc new file mode 100644 index 00000000000..074c16c40fb --- /dev/null +++ b/src/routes/docs/products/databases/postgresql/integrations/prisma/+page.markdoc @@ -0,0 +1,222 @@ +--- +layout: article +title: Prisma +description: Use Prisma ORM with an Appwrite native PostgreSQL database. Configure the Prisma 7 datasource, run migrations through the direct connection, and route serverless runtime traffic through the connection pooler. +--- + +[Prisma ORM](https://www.prisma.io/) works with Appwrite's native PostgreSQL database as a standard PostgreSQL target. Configure Prisma with the connection string from Appwrite, run Prisma Migrate against the direct database connection, and use Prisma Client from your application code. + +{% info title="Before you start" %} +You'll need a native PostgreSQL database in a `ready` state and its credentials. Open the database in the Console and click **Credentials** to copy values from the **Details**, **DSN**, **.env**, **Prisma**, **Drizzle**, or **psql** tabs. You can also call `postgresql.get()` from the Appwrite API to read `hostname`, `connectionUser`, `connectionPassword`, and `connectionString`. +{% /info %} + +# Initialize Prisma {% #initialize %} + +Install Prisma, Prisma Client, the PostgreSQL driver adapter, and the TypeScript tools used by the examples: + +```bash +npm install -D prisma typescript tsx @types/node @types/pg +npm install @prisma/client @prisma/adapter-pg dotenv pg +``` + +Initialize Prisma for PostgreSQL: + +```bash +npx prisma init --datasource-provider postgresql --output ../generated/prisma +``` + +Prisma 7 generates a `prisma.config.ts` file and a `prisma/schema.prisma` file. Set `"type": "module"` in `package.json` if your project does not already use ECMAScript modules. + +# Configure connection strings {% #connection-strings %} + +Copy the connection string from the Console **Credentials** view. Keep it in environment variables and do not commit it: + +```env +DATABASE_URL="postgresql://admin:<password>@db-<hash>.<region>.appwrite.center:5432/<database>?sslmode=require" +DIRECT_URL="postgresql://admin:<password>@db-<hash>.<region>.appwrite.center:5432/<database>?sslmode=require" +SHADOW_DATABASE_URL="postgresql://admin:<password>@db-<hash>.<region>.appwrite.center:5432/<database>?sslmode=require&schema=prisma_shadow" +``` + +`DATABASE_URL` is the runtime connection used by Prisma Client. `DIRECT_URL` is the direct database connection used by Prisma CLI commands. `SHADOW_DATABASE_URL` is required by `prisma migrate dev`, because Appwrite's `admin` user can run schema changes but cannot create additional PostgreSQL databases for Prisma's default shadow database workflow. + +Create the shadow schema once before you run `prisma migrate dev`: + +```sql +CREATE SCHEMA IF NOT EXISTS prisma_shadow; +``` + +Appwrite Cloud uses TLS for PostgreSQL connections, so keep `sslmode=require`. For full certificate verification or mTLS, see [Network security](/docs/products/databases/postgresql/network-security). + +# Configure Prisma {% #configure-prisma %} + +In `prisma.config.ts`, read the CLI connection strings from the environment: + +```ts +import "dotenv/config"; +import { defineConfig } from "prisma/config"; + +export default defineConfig({ + schema: "prisma/schema.prisma", + migrations: { + path: "prisma/migrations", + seed: "tsx prisma/seed.ts", + }, + datasource: { + url: process.env["DIRECT_URL"] ?? process.env["DATABASE_URL"], + shadowDatabaseUrl: process.env["SHADOW_DATABASE_URL"], + }, +}); +``` + +In `prisma/schema.prisma`, keep the datasource provider in the schema file and generate Prisma Client into the output directory created by `prisma init`: + +```prisma +generator client { + provider = "prisma-client" + output = "../generated/prisma" +} + +datasource db { + provider = "postgresql" +} + +model User { + id String @id @default(uuid()) + email String @unique + createdAt DateTime @default(now()) +} +``` + +If you are connecting to an existing database, run `npx prisma db pull` after you configure the environment variables to introspect its schema. + +# Pool connections from serverless {% #pooling %} + +Prisma Client opens database connections from each running application instance. On serverless platforms, many cold starts can quickly multiply the number of backend PostgreSQL connections. Route runtime traffic through the [connection pooler](/docs/products/databases/postgresql/connection-pooling) by using the pooler port, `6432`, for `DATABASE_URL` while keeping `DIRECT_URL` on the direct PostgreSQL port, `5432`, for migrations and introspection: + +```env +# Runtime: pooled connection through the Appwrite connection pooler +DATABASE_URL="postgresql://admin:<password>@db-<hash>.<region>.appwrite.center:6432/<database>?sslmode=require" + +# Prisma CLI: direct PostgreSQL connection for migrations and introspection +DIRECT_URL="postgresql://admin:<password>@db-<hash>.<region>.appwrite.center:5432/<database>?sslmode=require" + +# Prisma Migrate development shadow schema +SHADOW_DATABASE_URL="postgresql://admin:<password>@db-<hash>.<region>.appwrite.center:5432/<database>?sslmode=require&schema=prisma_shadow" +``` + +The pooler defaults to **transaction mode**, which gives the highest connection multiplexing. If your application depends on session-level features such as advisory locks, `LISTEN`/`NOTIFY`, temporary tables, or session-scoped prepared statements, switch the pooler to **session mode**. See [Connection pooling](/docs/products/databases/postgresql/connection-pooling#modes) for pool mode trade-offs. + +# Run migrations {% #migrate %} + +Generate and apply a migration in development: + +```bash +npx prisma migrate dev --name init +``` + +In CI or production, apply committed migrations without prompting: + +```bash +npx prisma migrate deploy +``` + +Generate Prisma Client after you install dependencies or change `prisma/schema.prisma`: + +```bash +npx prisma generate +``` + +The primary `admin` user owns the database and can run schema changes. Scoped [database roles](/docs/products/databases/postgresql/connections#roles), such as `readonly` and `readwrite` users, are intended for application access and should not run migrations. + +# Seed data {% #seed %} + +With the seed command configured in `prisma.config.ts`, add a seed script: + +```ts +import "dotenv/config"; +import { PrismaPg } from "@prisma/adapter-pg"; +import { PrismaClient } from "../generated/prisma/client"; + +const adapter = new PrismaPg( + { connectionString: process.env.DATABASE_URL! }, + { schema: process.env.DATABASE_SCHEMA }, +); + +const prisma = new PrismaClient({ adapter }); + +await prisma.user.upsert({ + where: { email: "ada@example.com" }, + update: {}, + create: { email: "ada@example.com" }, +}); + +await prisma.$disconnect(); +``` + +Run the seed command: + +```bash +npx prisma db seed +``` + +`DATABASE_SCHEMA` is optional. Set it only if you connect to a PostgreSQL schema other than `public`. + +# Query with Prisma Client {% #query %} + +Instantiate Prisma Client with the PostgreSQL driver adapter: + +```ts +import "dotenv/config"; +import { PrismaPg } from "@prisma/adapter-pg"; +import { PrismaClient } from "./generated/prisma/client"; + +const adapter = new PrismaPg( + { connectionString: process.env.DATABASE_URL! }, + { schema: process.env.DATABASE_SCHEMA }, +); + +const prisma = new PrismaClient({ adapter }); + +const user = await prisma.user.create({ + data: { email: "grace@example.com" }, +}); + +const recent = await prisma.user.findMany({ + orderBy: { createdAt: "desc" }, + take: 10, +}); + +console.log({ user, recent }); + +await prisma.$disconnect(); +``` + +On long-running servers, instantiate `PrismaClient` once and reuse it. On serverless platforms, keep a single client per module scope so warm invocations reuse it, and rely on the pooler to absorb cold-start connection churn. + +# Use a branch for previews and CI {% #branches %} + +[Branches](/docs/products/databases/postgresql/branches) are instant, isolated copies of a database with their own hostname and connection string. They are useful for running migrations against throwaway data in a pull-request preview or integration-test job: + +1. Create a branch from the API and read its `connectionString`. +2. Export it as `DIRECT_URL`, and use the pooled variant as `DATABASE_URL` if the branch has the pooler enabled. +3. Run `npx prisma migrate deploy` and your test suite against the branch. +4. Delete the branch when the job finishes. + +Because a branch starts from a storage snapshot, the schema and data match the source database at branch time, so migrations run against realistic data without touching production. + +# Related {% #related %} + +{% cards %} +{% cards_item href="/docs/products/databases/postgresql/connections" title="Connections" %} +Retrieve credentials, rotate the password, and create scoped connection users. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/connection-pooling" title="Connection pooling" %} +Pool modes, ports, and read/write splitting for serverless workloads. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/branches" title="Branches" %} +Ephemeral database copies for preview environments and CI. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/network-security" title="Network security" %} +TLS modes, certificate verification, mTLS, and IP allowlists. +{% /cards_item %} +{% /cards %} diff --git a/src/routes/docs/products/databases/postgresql/integrations/rails/+page.markdoc b/src/routes/docs/products/databases/postgresql/integrations/rails/+page.markdoc new file mode 100644 index 00000000000..125433ae833 --- /dev/null +++ b/src/routes/docs/products/databases/postgresql/integrations/rails/+page.markdoc @@ -0,0 +1,168 @@ +--- +layout: article +title: Rails +description: Use Ruby on Rails and ActiveRecord with an Appwrite native PostgreSQL database. Configure database.yml, run migrations against the direct database port, and size the ActiveRecord pool. +--- + +A native PostgreSQL database is a standard PostgreSQL engine, so [Ruby on Rails](https://rubyonrails.org/) works against it through ActiveRecord with no Appwrite-specific configuration. Point `config/database.yml` at the connection details from the [Connections](/docs/products/databases/postgresql/connections) page and use ActiveRecord, migrations, and the rest of the Rails toolchain exactly as you would against any PostgreSQL server. + +{% info title="Before you start" %} +You'll need a native PostgreSQL database in a `ready` state and its credentials. In the Appwrite Console, open the database and click **Credentials**. Use the **Details** tab for individual values, or copy a ready-made string from the **DSN**, **.env**, **Prisma**, **Drizzle**, or **psql** tab. You can also call `postgresql.get()` from the Appwrite API to read `hostname`, `connectionUser`, `connectionPassword`, and `connectionString`. The primary user is `admin`, and the database name is generated for each database. +{% /info %} + +# Install the database driver {% #driver %} + +ActiveRecord talks to PostgreSQL through the `pg` driver gem. Add it to your `Gemfile`: + +```ruby +# Gemfile +gem 'pg' +``` + +The `pg` gem builds against `libpq`, so the PostgreSQL client headers must be available at install time. + +Then install: + +```bash +bundle install +``` + +# Set the connection string {% #connection-string %} + +Copy the connection string from the Console **Credentials** dialog, or fetch it with the [API](/docs/products/databases/postgresql/connections#credentials). Keep it in an environment variable and do not commit it: + +```env +DATABASE_URL="postgresql://admin:<password>@db-<hash>.<region>.appwrite.center:5432/<database>?sslmode=require" +``` + +The TLS parameter (`sslmode=require`) is already part of the string Appwrite returns. Appwrite Cloud terminates TLS at the edge, so no extra certificate configuration is needed. For full certificate verification (`verify-full`) or mTLS, see the [Network](/docs/products/databases/postgresql/network-security) page. + +# Configure database.yml {% #database-yml %} + +Rails reads `DATABASE_URL` automatically. The simplest configuration points the `url` at the environment variable and lets ActiveRecord parse the host, port, database, and credentials out of it: + +```yaml +# config/database.yml +production: + adapter: postgresql + url: <%= ENV["DATABASE_URL"] %> + pool: <%= ENV.fetch("RAILS_MAX_THREADS", 5) %> +``` + +If you'd rather set the fields explicitly, the discrete keys map one-to-one to the values from the [Connections](/docs/products/databases/postgresql/connections#credentials) response. Use ERB to read each value from the environment so no secret lands in source control: + +```yaml +# config/database.yml +production: + adapter: postgresql + host: <%= ENV["DB_HOST"] %> # db-<hash>.<region>.appwrite.center + port: <%= ENV.fetch("DB_PORT", 5432) %> + database: <%= ENV["DB_NAME"] %> # <database> + username: <%= ENV.fetch("DB_USER", "admin") %> + password: <%= ENV["DB_PASSWORD"] %> + sslmode: require + pool: <%= ENV.fetch("RAILS_MAX_THREADS", 5) %> +``` + +When both `DATABASE_URL` and explicit keys are present, Rails merges them. `sslmode` and `pool` can still be set in `database.yml`, so a `url`-based config can carry the TLS parameter in the string and override `pool` in the YAML. + +# Size the connection pool {% #pool %} + +ActiveRecord manages a per-process connection pool. The `pool:` value caps how many backend connections a single Rails process holds, and it defaults to `5`. It must be large enough for every thread that checks out a connection, your Puma worker threads plus any background job threads in the same process. + +```yaml +production: + adapter: postgresql + url: <%= ENV["DATABASE_URL"] %> + pool: <%= ENV.fetch("RAILS_MAX_THREADS", 5) %> +``` + +Tying `pool` to `RAILS_MAX_THREADS` keeps it aligned with Puma's thread count. Each Puma **worker** is a separate process with its own pool, so the backend connection count is roughly `pool × workers × server instances`. Keep that product within your specification's `maxConnections`, see [specifications](/docs/products/databases/postgresql#specifications). + +# Run migrations {% #migrate %} + +Generate and apply migrations the usual way: + +```bash +bin/rails db:migrate +``` + +Migrations issue DDL and need a session-level connection, so run them against the direct PostgreSQL port `5432`, not the transaction-mode pooler. Point `DATABASE_URL` (or a separate migration URL) at the direct port when you run `db:migrate`. The primary `admin` user owns the database and can run schema changes. Narrower [database roles](/docs/products/databases/postgresql/connections#roles) should only receive the privileges your application needs. + +# Use ActiveRecord {% #activerecord %} + +Once `database.yml` is configured, models work with no further setup. Define a migration and model, then query through ActiveRecord: + +```ruby +# db/migrate/20240101000000_create_users.rb +class CreateUsers < ActiveRecord::Migration[7.1] + def change + create_table :users do |t| + t.string :email, null: false + t.timestamps + end + add_index :users, :email, unique: true + end +end +``` + +```ruby +# app/models/user.rb +class User < ApplicationRecord + validates :email, presence: true, uniqueness: true +end +``` + +```ruby +User.create!(email: 'ada@example.com') + +recent = User.order(created_at: :desc).limit(10) +``` + +ActiveRecord opens connections lazily and reuses them from the pool, so a long-running Puma server keeps a small, stable set of backend connections rather than opening one per request. + +# Pooling for a long-running server {% #pooling %} + +A Rails app under Puma is a long-running process: it holds an ActiveRecord pool for its lifetime. That pairs naturally with the direct PostgreSQL port `5432`, sized so `pool × workers` stays within your connection budget. This is the recommended setup for a persistent server. + +If you instead route through the [connection pooler](/docs/products/databases/postgresql/connection-pooling) to absorb spikes or many app instances, prefer **session mode**, which keeps a backend connection for the whole client session and behaves like a direct connection to ActiveRecord. The pooler defaults to **transaction mode**, which hands out a different backend connection per transaction. ActiveRecord uses server-side prepared statements by default, and those are tied to one backend connection, so on the transaction-mode pooler you must disable them: + +```yaml +production: + adapter: postgresql + url: <%= ENV["DATABASE_URL"] %> # pooler host, port 6432 + pool: <%= ENV.fetch("RAILS_MAX_THREADS", 5) %> + prepared_statements: false +``` + +See the [pooler](/docs/products/databases/postgresql/connection-pooling#modes) page for the mode trade-offs. Whichever runtime connection you choose, always run `bin/rails db:migrate` against the direct PostgreSQL port. + +# Use a branch for previews and CI {% #branches %} + +[Branches](/docs/products/databases/postgresql/branches) are instant, isolated copies of a database with their own hostname and connection string. They're ideal for running migrations against throwaway data in a pull-request preview or an integration-test job: + +1. Create a branch from the API and read its `connectionString`. +2. Export it as `DATABASE_URL` for the job. +3. Run `bin/rails db:migrate` and your test suite against the branch. +4. Delete the branch when the job finishes. + +A branch has no pooler and exposes the PostgreSQL port directly, which gives migrations the session-level connection they need. Because a branch starts from a storage snapshot, the schema and data match the source database at branch time, so migrations run against realistic data without touching production. + +# Related {% #related %} + +{% cards %} +{% cards_item href="/docs/products/databases/postgresql/connections" title="Connections" %} +Retrieve credentials, rotate the password, and create database roles. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/connection-pooling" title="Connection pooler" %} +Pool modes, ports, and read/write splitting for high-concurrency workloads. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/branches" title="Branches" %} +Ephemeral database copies for preview environments and CI. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/network-security" title="Network" %} +TLS modes, certificate verification, mTLS, and IP allowlists. +{% /cards_item %} +{% /cards %} + +For ActiveRecord and migration details beyond this guide, see the [Rails configuration guide](https://guides.rubyonrails.org/configuring.html). diff --git a/src/routes/docs/products/databases/postgresql/integrations/retool/+page.markdoc b/src/routes/docs/products/databases/postgresql/integrations/retool/+page.markdoc new file mode 100644 index 00000000000..ea28a048987 --- /dev/null +++ b/src/routes/docs/products/databases/postgresql/integrations/retool/+page.markdoc @@ -0,0 +1,95 @@ +--- +layout: article +title: Retool +description: Connect Retool to an Appwrite native PostgreSQL database to build internal and admin tools. Retrieve credentials from the Console, configure the PostgreSQL resource with TLS, and allow Retool Cloud network access when needed. +--- + +An Appwrite [native PostgreSQL database](/docs/products/databases/postgresql) exposes a standard PostgreSQL connection, so [Retool](https://retool.com/) connects to it through the built-in **PostgreSQL** resource. Use the database hostname, generated database name, and credentials from Appwrite, then build queries, tables, and forms in Retool for dashboards and admin panels. + +{% info title="Before you start" %} +You'll need a native PostgreSQL database in a `ready` state and permission to create resources in Retool. In the Appwrite Console, open the database and click **Credentials**. Use the **Details** tab for individual values, or copy a ready-made string from the **DSN**, **.env**, **Prisma**, **Drizzle**, or **psql** tab. You can also fetch credentials with the API by calling `postgresql.get()`, which returns `hostname`, `connectionUser`, `connectionPassword`, and `connectionString`. See [Connections](/docs/products/databases/postgresql/connections) for the full flow. +{% /info %} + +# Choose credentials {% #credentials %} + +The primary user is `admin`, and the database name is generated for each database. The connection string has this form: `postgresql://admin:<password>@db-<hash>.<region>.appwrite.center:5432/<database>`. + +Use `admin` for initial setup or schema work because it owns the database and can run DDL. For a Retool app that only needs application-level access, create a narrower PostgreSQL role from the database **Roles** tab in the Console, then grant only the table privileges the app needs from the SQL editor or `psql`. For example, a dashboard role usually needs `SELECT`, while an admin tool may need `SELECT`, `INSERT`, `UPDATE`, and `DELETE` on specific tables. + +{% arrow_link href="/docs/products/databases/postgresql/connections#roles" %} +Read more about database roles +{% /arrow_link %} + +# Create the PostgreSQL resource {% #resource %} + +In Retool, go to **Resources**, click **Create new** > **Resource**, search for `PostgreSQL`, and select the PostgreSQL tile. Give the resource a clear **Name** and optional **Description** that identifies the Appwrite database and environment. + +In **Resource credentials**, either paste the Appwrite connection string or fill in the fields manually: + +| Retool setting | Value | +|----------------|-------| +| Host | `db-<hash>.<region>.appwrite.center` | +| Port | `5432` | +| Database name | `<database>` | +| Connection options | Optional PostgreSQL parameters, such as `application_name=retool` | +| Authentication | **Username and password** | +| Username | `admin` or a narrower PostgreSQL role | +| Password | The password from the Appwrite credentials dialog or API response | + +In **Advanced options**, choose an outbound region if your Retool organization uses regional egress and you want the resource traffic to originate near your Appwrite database. + +Enable **SSL/TLS**. Appwrite Cloud terminates TLS at the edge, and the certificate is signed by a public CA. If Retool shows **Reject unauthorized**, keep it enabled. If Retool shows **Verification mode**, choose **Full verification**. Leave **CA certificate** empty. + +Click **Test connection**. If the test succeeds, click **Create resource**. + +# Pick the connection path {% #connection-path %} + +For most Retool apps, connect directly to PostgreSQL on port `5432`. Retool uses prepared statements for PostgreSQL queries, and Appwrite's transaction-mode pooler does not preserve session-level state across statements. If you use the Appwrite [connection pooler](/docs/products/databases/postgresql/connection-pooling), configure it in **session** mode for Retool. + +{% arrow_link href="/docs/products/databases/postgresql/connection-pooling#modes" %} +Compare pooler modes +{% /arrow_link %} + +# Allow Retool Cloud through the network {% #network %} + +If you enabled an [IP allowlist](/docs/products/databases/postgresql/network-security#ip-allowlist) for the database, add the Retool Cloud egress addresses for the resource's outbound region. Retool's default outbound region is `us-west-2`, and Retool also documents `eu-central-1` and `ap-southeast-1` egress addresses. Retrieve the current list from [Retool's IP address documentation](https://docs.retool.com/data-sources/reference/ip-allowlist-cloud-orgs) instead of copying static addresses into your runbook. + +If you leave the database allowlist open, rely on TLS plus database credentials and least-privilege roles to protect access. + +{% arrow_link href="/docs/products/databases/postgresql/network-security#ip-allowlist" %} +Configure the IP allowlist +{% /arrow_link %} + +# Build an admin tool {% #build %} + +After the resource is connected, create PostgreSQL queries in Retool and wire them to components: + +- Use **SQL mode** for read queries that feed a **Table**, chart, or other display component. +- Use **GUI mode** actions such as **Insert a record**, **Update an existing record**, and **Delete a record** for forms and editable tables. +- Bind table edits to the **Save changes** event and refresh the read query after writes complete. +- Show a confirmation modal before delete actions. + +Reference component values with Retool's `{{ }}` embedded expressions. Retool converts PostgreSQL queries to prepared statements by default, which separates values from SQL text and helps prevent SQL injection. Keep that protection enabled unless you have a specific, reviewed reason to disable it. + +Use database roles as the last line of defense. A dashboard role with only `SELECT` cannot write even if a query is misconfigured. A data-entry role with table-level write privileges can create, update, and delete rows without also owning the schema. + +# Use a branch for staging {% #branches %} + +[Branches](/docs/products/databases/postgresql/branches) are API-created, isolated copies of a PostgreSQL database with their own connection details. Create a branch for staging or preview work, fetch its `connectionString`, and configure a second Retool PostgreSQL resource against that branch. Delete the branch when the staging tool is no longer needed. + +# Related {% #related %} + +{% cards %} +{% cards_item href="/docs/products/databases/postgresql" title="PostgreSQL" %} +Create and manage a native PostgreSQL database. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/connections" title="Connections" %} +Retrieve credentials, rotate the primary password, and create database roles. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/network-security" title="Network security" %} +TLS, IP allowlists, and other network controls. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/branches" title="Branches" %} +Create isolated database copies for staging and preview environments. +{% /cards_item %} +{% /cards %} diff --git a/src/routes/docs/products/databases/postgresql/integrations/spring-boot/+page.markdoc b/src/routes/docs/products/databases/postgresql/integrations/spring-boot/+page.markdoc new file mode 100644 index 00000000000..773cf725f09 --- /dev/null +++ b/src/routes/docs/products/databases/postgresql/integrations/spring-boot/+page.markdoc @@ -0,0 +1,182 @@ +--- +layout: article +title: Spring Boot +description: Connect a Spring Boot application to an Appwrite native PostgreSQL database with Spring Data JPA and Hibernate. Configure the JDBC datasource and HikariCP pool, map entities, and run Flyway or Liquibase migrations against PostgreSQL. +--- + +An Appwrite native PostgreSQL database is a standard PostgreSQL engine, so a Spring Boot application connects to it through the PostgreSQL JDBC driver with no Appwrite-specific runtime configuration. Point `spring.datasource` at the JDBC URL from your database credentials, size the built-in HikariCP pool, and use Spring Data JPA, Hibernate, Flyway, or Liquibase as you would with any managed PostgreSQL server. + +{% info title="Before you start" %} +You'll need a native PostgreSQL database in a `ready` state and its credentials. In the Appwrite Console, open the database and click **Credentials**. Use the **Details** tab for individual values, or copy a ready-made string from the **DSN**, **.env**, **Prisma**, **Drizzle**, or **psql** tab. You can also fetch credentials with the API by calling `postgresql.get()`, which returns `hostname`, `connectionUser`, `connectionPassword`, and `connectionString`. See [Connections](/docs/products/databases/postgresql/connections) for the full flow. +{% /info %} + +# Add the dependencies {% #dependencies %} + +A Spring Data JPA application needs the JPA starter and the PostgreSQL JDBC driver. HikariCP ships with `spring-boot-starter-data-jpa`, and Spring Boot picks the driver class from the JDBC URL. + +```text +org.springframework.boot:spring-boot-starter-data-jpa +org.postgresql:postgresql +``` + +If you use Flyway or Liquibase, add that migration tool through Spring Initializr or your build file as well. Current Spring Boot projects that use Flyway with PostgreSQL include the Flyway integration and `org.flywaydb:flyway-database-postgresql`. + +# Configure the datasource {% #datasource %} + +Build the JDBC URL from the host and database name in the credentials dialog. Appwrite uses port `5432`, the primary user is `admin`, and the database name is generated per database. Read the password from the environment: + +```yaml +spring: + datasource: + url: jdbc:postgresql://db-<hash>.<region>.appwrite.center:5432/<database>?sslmode=require + username: admin + password: ${DB_PASSWORD} + hikari: + maximum-pool-size: 10 + minimum-idle: 2 + connection-timeout: 30000 + max-lifetime: 1200000 + jpa: + hibernate: + ddl-auto: validate +``` + +The equivalent `application.properties`: + +```ini +spring.datasource.url=jdbc:postgresql://db-<hash>.<region>.appwrite.center:5432/<database>?sslmode=require +spring.datasource.username=admin +spring.datasource.password=${DB_PASSWORD} +spring.datasource.hikari.maximum-pool-size=10 +spring.datasource.hikari.minimum-idle=2 +spring.datasource.hikari.connection-timeout=30000 +spring.datasource.hikari.max-lifetime=1200000 +spring.jpa.hibernate.ddl-auto=validate +``` + +`sslmode=require` enables TLS for the PostgreSQL connection. If your security policy requires host certificate validation, configure pgJDBC with `sslmode=verify-full` and a JVM trust configuration that trusts the certificate chain. The [Network security](/docs/products/databases/postgresql/network-security) page covers TLS, mTLS, and IP allowlists. + +# Size the HikariCP pool {% #pool %} + +A Spring Boot server is long-running, so it holds its HikariCP pool open for the lifetime of the process. Keep `maximum-pool-size` modest. HikariCP guidance is that throughput usually peaks at a small pool, roughly `(CPU cores x 2) + 1` for the database, not hundreds of connections. A pool that exceeds what PostgreSQL can serve only queues work inside the database and adds latency. + +Each replica of your application opens its own pool, so multiply `maximum-pool-size` by the number of instances and keep the total under the connection budget of your native PostgreSQL database [specification](/docs/products/databases/postgresql#specifications). Set `max-lifetime` a little below your infrastructure's idle timeout so HikariCP recycles connections before they are closed. + +# Map an entity {% #entity %} + +Define a JPA entity and a Spring Data repository as usual. This example uses a prefixed table name so it is easy to identify in a shared database: + +```java +package com.example.demo; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; + +@Entity +@Table(name = "users") +public class User { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false, unique = true) + private String email; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } +} +``` + +```java +package com.example.demo; + +import java.util.Optional; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface UserRepository extends JpaRepository<User, Long> { + Optional<User> findByEmail(String email); +} +``` + +Inject the repository wherever you need it and call `save`, `findById`, `findByEmail`, and the rest of the generated query methods. HikariCP hands each transaction a pooled connection and returns it on commit. + +# Run migrations {% #migrate %} + +Let a migration tool own the schema and set `ddl-auto: validate` so Hibernate checks the mapping against the live tables at startup but never alters them. Add Flyway or Liquibase to your build and Spring Boot runs pending migrations automatically on boot. + +For example, a Flyway migration at `src/main/resources/db/migration/V1__init.sql` can create the table used by the entity above: + +```sql +CREATE TABLE users ( + id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, + email VARCHAR(255) NOT NULL UNIQUE +); +``` + +Flyway reads versioned scripts from `src/main/resources/db/migration`. Point Flyway at the direct PostgreSQL port `5432` so migrations run on a session connection with DDL privileges. Setting `spring.flyway.url` gives Flyway its own datasource, independent of the runtime pool: + +```ini +spring.flyway.url=jdbc:postgresql://db-<hash>.<region>.appwrite.center:5432/<database>?sslmode=require +spring.flyway.user=admin +spring.flyway.password=${DB_PASSWORD} +``` + +Liquibase is equivalent: it reads a changelog from `src/main/resources/db/changelog` and accepts its own `spring.liquibase.url`, `spring.liquibase.user`, and `spring.liquibase.password` pointing at the same PostgreSQL port. + +The primary `admin` user owns the database and can run schema changes. Scoped [database roles](/docs/products/databases/postgresql/connections#roles) intentionally cannot run DDL, so run migrations as `admin`. + +# Pooling and the connection pooler {% #pooling %} + +HikariCP is already a connection pool, so a long-running Spring Boot server should connect to the direct PostgreSQL port `5432` and let HikariCP manage connections. Routing a server's traffic through the [connection pooler](/docs/products/databases/postgresql/connection-pooling) in `transaction` mode stacks HikariCP on top of a transaction pooler and can break server-side prepared statements, which the PostgreSQL JDBC driver uses. + +If you put the pooler in front of your server, use `session` mode so PostgreSQL keeps a backend connection for the whole client session and preserves prepared statements. Connect HikariCP on the pooler port `6432` and keep `maximum-pool-size` small. See the [connection pooler](/docs/products/databases/postgresql/connection-pooling#modes) page for the mode trade-offs. Always run Flyway or Liquibase against port `5432` regardless of how runtime traffic connects. + +# Use a branch for previews and CI {% #branches %} + +[Branches](/docs/products/databases/postgresql/branches) are instant, isolated copies of a database with their own hostname and connection string. They are useful for running migrations against throwaway data in a pull-request preview or integration-test job. + +1. Create a branch with the API and read its `connectionString`. +2. Convert the connection string to a JDBC URL and inject it into `spring.datasource.url`, or split it into `spring.datasource.url`, `spring.datasource.username`, and `spring.datasource.password`. +3. Boot the application so Flyway or Liquibase applies migrations, then run your test suite against the branch. +4. Delete the branch when the job finishes. + +Because a branch starts from a storage snapshot, the schema and data match the source database at branch time, so migrations and `@DataJpaTest` integration tests run against realistic data without touching production. + +# Related {% #related %} + +{% cards %} +{% cards_item href="/docs/products/databases/postgresql/connections" title="Connections" %} +Retrieve credentials, rotate the password, and create scoped database roles. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/connection-pooling" title="Connection pooler" %} +Pool modes, ports, and read/write splitting for the connection pooler. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/branches" title="Branches" %} +Ephemeral database copies for preview environments and CI. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/network-security" title="Network security" %} +TLS modes, certificate verification, mTLS, and IP allowlists. +{% /cards_item %} +{% /cards %} + +{% arrow_link href="/docs/products/databases/postgresql" %} +Back to native PostgreSQL overview +{% /arrow_link %} diff --git a/src/routes/docs/products/databases/postgresql/maintenance/+page.markdoc b/src/routes/docs/products/databases/postgresql/maintenance/+page.markdoc new file mode 100644 index 00000000000..238b636f6a5 --- /dev/null +++ b/src/routes/docs/products/databases/postgresql/maintenance/+page.markdoc @@ -0,0 +1,651 @@ +--- +layout: article +title: Maintenance +description: Maintenance windows, online engine version upgrades, pause and resume, and the lifecycle states of your PostgreSQL database. +--- + +Appwrite manages the infrastructure around your database: security patches, engine upgrades, and instance health. This page covers the controls you have over when and how that maintenance happens. + +# Maintenance window {% #window %} + +Routine maintenance that can briefly affect the database runs inside a weekly window that you choose. Set it under **Settings** > **Maintenance** in the Console by picking a day and start hour (UTC), or through the API: + +{% multicode %} +```server-nodejs +import { Client, Postgresql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +await postgresql.updateMaintenance({ + databaseId: '<DATABASE_ID>', + day: 'sun', + hourUtc: 3, +}); +``` +```server-deno +import { Client, Postgresql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +await postgresql.updateMaintenance({ + databaseId: '<DATABASE_ID>', + day: 'sun', + hourUtc: 3, +}); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Postgresql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$postgresql = new Postgresql($client); + +$postgresql->updateMaintenance( + databaseId: '<DATABASE_ID>', + day: 'sun', + hourUtc: 3, +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.postgresql import Postgresql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +postgresql = Postgresql(client) + +postgresql.update_maintenance( + database_id='<DATABASE_ID>', + day='sun', + hour_utc=3, +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +postgresql = Postgresql.new(client) + +postgresql.update_maintenance( + database_id: '<DATABASE_ID>', + day: 'sun', + hour_utc: 3, +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Postgresql postgresql = new Postgresql(client); + +await postgresql.UpdateMaintenance( + databaseId: "<DATABASE_ID>", + day: "sun", + hourUtc: 3 +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Postgresql postgresql = Postgresql(client); + +await postgresql.updateMaintenance( + databaseId: '<DATABASE_ID>', + day: 'sun', + hourUtc: 3, +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Postgresql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val postgresql = Postgresql(client) + +postgresql.updateMaintenance( + databaseId = "<DATABASE_ID>", + day = "sun", + hourUtc = 3, +) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let postgresql = Postgresql(client) + +_ = try await postgresql.updateMaintenance( + databaseId: "<DATABASE_ID>", + day: "sun", + hourUtc: 3 +) +``` +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewPostgresql(client) + + _, err := service.UpdateMaintenance("<DATABASE_ID>", "sun", 3) + if err != nil { + panic(err) + } +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::postgresql::Postgresql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let postgresql = Postgresql::new(&client); + + postgresql.update_maintenance("<DATABASE_ID>", "sun", 3).await?; + + Ok(()) +} +``` +```bash +curl -X PATCH \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <API_KEY>" \ + -H "Content-Type: application/json" \ + -d '{ + "day": "sun", + "hourUtc": 3 + }' \ + https://<REGION>.cloud.appwrite.io/v1/postgresql/<DATABASE_ID>/maintenance +``` +{% /multicode %} + +`day` accepts `sun` through `sat`, and `hourUtc` accepts `0` to `23`. + +# Engine version upgrades {% #upgrades %} + +You can upgrade the PostgreSQL version online. A second instance is provisioned on the target version, data streams over with logical replication, and traffic cuts over once replication has caught up, with no read or write outage: + +{% multicode %} +```server-nodejs +import { Client, Postgresql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +await postgresql.createUpgrade({ + databaseId: '<DATABASE_ID>', + targetVersion: '18', +}); +``` +```server-deno +import { Client, Postgresql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +await postgresql.createUpgrade({ + databaseId: '<DATABASE_ID>', + targetVersion: '18', +}); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Postgresql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$postgresql = new Postgresql($client); + +$postgresql->createUpgrade( + databaseId: '<DATABASE_ID>', + targetVersion: '18', +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.postgresql import Postgresql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +postgresql = Postgresql(client) + +postgresql.create_upgrade( + database_id='<DATABASE_ID>', + target_version='18', +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +postgresql = Postgresql.new(client) + +postgresql.create_upgrade( + database_id: '<DATABASE_ID>', + target_version: '18', +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Postgresql postgresql = new Postgresql(client); + +await postgresql.CreateUpgrade( + databaseId: "<DATABASE_ID>", + targetVersion: "18" +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Postgresql postgresql = Postgresql(client); + +await postgresql.createUpgrade( + databaseId: '<DATABASE_ID>', + targetVersion: '18', +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Postgresql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val postgresql = Postgresql(client) + +postgresql.createUpgrade( + databaseId = "<DATABASE_ID>", + targetVersion = "18", +) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let postgresql = Postgresql(client) + +_ = try await postgresql.createUpgrade( + databaseId: "<DATABASE_ID>", + targetVersion: "18" +) +``` +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewPostgresql(client) + + _, err := service.CreateUpgrade("<DATABASE_ID>", "18") + if err != nil { + panic(err) + } +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::postgresql::Postgresql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let postgresql = Postgresql::new(&client); + + postgresql.create_upgrade("<DATABASE_ID>", "18").await?; + + Ok(()) +} +``` +```bash +curl -X POST \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <API_KEY>" \ + -H "Content-Type: application/json" \ + -d '{ + "targetVersion": "18" + }' \ + https://<REGION>.cloud.appwrite.io/v1/postgresql/<DATABASE_ID>/upgrades +``` +{% /multicode %} + +Before a major version upgrade, check that your installed [extensions](/docs/products/databases/postgresql/extensions) support the target version. + +# Pause and resume {% #pause-resume %} + +{% only_dark %} +![Database settings status card](/images/docs/products/databases/postgresql/dark/settings.avif) +{% /only_dark %} +{% only_light %} +![Database settings status card](/images/docs/products/databases/postgresql/settings.avif) +{% /only_light %} + +A paused database stops its compute but keeps its storage, configuration, and credentials. Pause a database you are not using to stop paying for compute; resume it when you need it again. In the Console, use the **Running** toggle on the **Settings** page. From the API, update the status: + +{% multicode %} +```server-nodejs +import { Client, Postgresql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +await postgresql.update({ + databaseId: '<DATABASE_ID>', + status: 'paused', +}); +``` +```server-deno +import { Client, Postgresql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +await postgresql.update({ + databaseId: '<DATABASE_ID>', + status: 'paused', +}); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Postgresql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$postgresql = new Postgresql($client); + +$postgresql->update( + databaseId: '<DATABASE_ID>', + status: 'paused', +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.postgresql import Postgresql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +postgresql = Postgresql(client) + +postgresql.update( + database_id='<DATABASE_ID>', + status='paused', +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +postgresql = Postgresql.new(client) + +postgresql.update( + database_id: '<DATABASE_ID>', + status: 'paused', +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Postgresql postgresql = new Postgresql(client); + +await postgresql.Update( + databaseId: "<DATABASE_ID>", + status: "paused" +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Postgresql postgresql = Postgresql(client); + +await postgresql.update( + databaseId: '<DATABASE_ID>', + status: 'paused', +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Postgresql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val postgresql = Postgresql(client) + +postgresql.update( + databaseId = "<DATABASE_ID>", + status = "paused", +) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let postgresql = Postgresql(client) + +_ = try await postgresql.update( + databaseId: "<DATABASE_ID>", + status: "paused" +) +``` +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" + "github.com/appwrite/sdk-for-go/postgresql" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewPostgresql(client) + + _, err := service.Update( + "<DATABASE_ID>", + postgresql.WithUpdateStatus("paused"), + ) + if err != nil { + panic(err) + } +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::postgresql::Postgresql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let postgresql = Postgresql::new(&client); + + postgresql.update("<DATABASE_ID>", None, Some("paused"), None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None).await?; + + Ok(()) +} +``` +```bash +curl -X PATCH \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <API_KEY>" \ + -H "Content-Type: application/json" \ + -d '{ + "status": "paused" + }' \ + https://<REGION>.cloud.appwrite.io/v1/postgresql/<DATABASE_ID> +``` +{% /multicode %} + +Set `status` back to `ready` to resume. Both transitions are asynchronous: the request returns immediately and the database moves through `pausing` or `resuming` before settling. A database in the `failed` state can also be recovered by setting its status to `ready`. + +# Lifecycle states {% #states %} + +| Status | Meaning | +|----------------|------------------------------------------------------------------| +| `provisioning` | Being created | +| `ready` | Online and accepting connections | +| `scaling` | A configuration or specification change is being applied | +| `pausing` | Transitioning to paused | +| `paused` | Compute stopped, storage retained | +| `resuming` | Transitioning back to ready | +| `restoring` | A backup or point-in-time restore is in progress | +| `failed` | An infrastructure error occurred; the database can be resumed | + +# Deleting a database {% #delete %} + +Delete a database from **Settings** > **Delete database** in the Console, or programmatically. Deletion stops billing and invalidates the credentials immediately. Deleting a database also deletes its backups, so export anything you need first. diff --git a/src/routes/docs/products/databases/postgresql/monitoring/+page.markdoc b/src/routes/docs/products/databases/postgresql/monitoring/+page.markdoc new file mode 100644 index 00000000000..9dfb2df04f9 --- /dev/null +++ b/src/routes/docs/products/databases/postgresql/monitoring/+page.markdoc @@ -0,0 +1,235 @@ +--- +layout: article +title: Monitoring +description: Watch compute, connections, storage, and workload metrics live, inspect active connections, and check database health on your PostgreSQL database. +--- + +Every native database ships with built-in observability: live metrics in the Console, an active-connections inspector, and programmatic health checks. There is nothing to install; metrics collection runs next to the database. + +# Monitor tab {% #monitor %} + +{% only_dark %} +![Database monitor tab](/images/docs/products/databases/postgresql/dark/monitor.avif) +{% /only_dark %} +{% only_light %} +![Database monitor tab](/images/docs/products/databases/postgresql/monitor.avif) +{% /only_light %} + +Open your database and select the **Monitor** tab. The view is organized into sections: + +- **Overview**: key health indicators at a glance, including connection usage against your limit, storage used, cache hit ratio, uptime, and commit/rollback counts +- **Compute**: CPU and memory usage over time +- **Connections**: connection counts by state and by application +- **Storage**: disk usage and growth +- **Workload**: query throughput and activity + +Use the date range picker to zoom into an incident window, and **Refresh metrics** to pull the latest samples. + +A healthy OLTP database typically shows a cache hit ratio above 99%. A sustained lower ratio means the working set does not fit in memory, which is usually solved by moving up a [specification](/docs/products/databases/postgresql/scaling). + +# Active connections {% #connections %} + +{% only_dark %} +![Active connections tab](/images/docs/products/databases/postgresql/dark/connections.avif) +{% /only_dark %} +{% only_light %} +![Active connections tab](/images/docs/products/databases/postgresql/connections.avif) +{% /only_light %} + +The **Connections** tab lists live connections from PostgreSQL's `pg_stat_activity`, with the connection state, duration, client, application name, and current query for each. + +You can filter by state (**Active**, **Idle**, **Idle in transaction**, **Long-running**), and act on problem connections directly: cancel a running query, terminate a connection, or terminate all idle-in-transaction sessions at once. Idle-in-transaction sessions hold locks and block vacuum, so terminating them is often the fastest way to unblock a stuck workload. + +# Database health {% #status %} + +Poll the database status for live health information: readiness, uptime, connection counts, replica state, and storage volumes. Use it from deploy pipelines to wait for the database, or from your own monitoring: + +{% multicode %} +```server-nodejs +import { Client, Postgresql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +const status = await postgresql.getStatus({ + databaseId: '<DATABASE_ID>', +}); +``` +```server-deno +import { Client, Postgresql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +const status = await postgresql.getStatus({ + databaseId: '<DATABASE_ID>', +}); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Postgresql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$postgresql = new Postgresql($client); + +$status = $postgresql->getStatus( + databaseId: '<DATABASE_ID>', +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.postgresql import Postgresql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +postgresql = Postgresql(client) + +status = postgresql.get_status( + database_id='<DATABASE_ID>', +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +postgresql = Postgresql.new(client) + +status = postgresql.get_status( + database_id: '<DATABASE_ID>', +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Postgresql postgresql = new Postgresql(client); + +var status = await postgresql.GetStatus( + databaseId: "<DATABASE_ID>" +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Postgresql postgresql = Postgresql(client); + +final status = await postgresql.getStatus( + databaseId: '<DATABASE_ID>', +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Postgresql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val postgresql = Postgresql(client) + +val status = postgresql.getStatus( + databaseId = "<DATABASE_ID>", +) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let postgresql = Postgresql(client) + +let status = try await postgresql.getStatus( + databaseId: "<DATABASE_ID>" +) +``` +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewPostgresql(client) + + result, err := service.GetStatus("<DATABASE_ID>") + if err != nil { + panic(err) + } + _ = result +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::postgresql::Postgresql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let postgresql = Postgresql::new(&client); + + let status = postgresql.get_status("<DATABASE_ID>").await?; + + Ok(()) +} +``` +```bash +curl -X GET \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <API_KEY>" \ + https://<REGION>.cloud.appwrite.io/v1/postgresql/<DATABASE_ID>/status +``` +{% /multicode %} + +For the database lifecycle state (`ready`, `scaling`, `restoring`, and friends), read the `status` field of the database object itself; see [lifecycle states](/docs/products/databases/postgresql/maintenance#states). + +# Explain a query {% #explain %} + +The Console's **SQL editor** tab has an **Explain** button that shows the execution plan for the query in the editor, without leaving the browser. Use it to check whether a slow query uses your indexes before reaching for `EXPLAIN ANALYZE` in `psql`. diff --git a/src/routes/docs/products/databases/postgresql/network-security/+page.markdoc b/src/routes/docs/products/databases/postgresql/network-security/+page.markdoc new file mode 100644 index 00000000000..0763884894a --- /dev/null +++ b/src/routes/docs/products/databases/postgresql/network-security/+page.markdoc @@ -0,0 +1,463 @@ +--- +layout: article +title: Network security +description: TLS by default, IP allowlists, and idle timeouts for your PostgreSQL database. +--- + +Every native database is reachable through a unique public hostname, secured with TLS, and protected by network controls that you configure per database. + +# Hostname {% #hostname %} + +Each database gets a stable hostname in the form: + +``` +db-<hash>.<region>.appwrite.center +``` + +The hostname does not change for the lifetime of the database, across restarts, resizes, failovers, and version upgrades. You can copy it from the Console credentials dialog or the database response. + +# TLS {% #tls %} + +Connections on Appwrite Cloud are encrypted with TLS, terminated at Appwrite's edge and forwarded to your database over the internal network. The connection string from the credentials dialog carries the right SSL settings for your environment, so drivers need no extra configuration. + +# IP allowlist {% #ip-allowlist %} + +{% only_dark %} +![Network settings](/images/docs/products/databases/postgresql/dark/settings-network.avif) +{% /only_dark %} +{% only_light %} +![Network settings](/images/docs/products/databases/postgresql/settings-network.avif) +{% /only_light %} + +By default, any host that has your credentials can reach the database over the public internet. To restrict access to known networks, configure an IP allowlist. Connections from addresses outside the allowlist are dropped at the network layer, before authentication. + +In the Console, add entries under **Settings** > **Network**. + +From the API, pass CIDR blocks or single addresses: + +{% multicode %} +```server-nodejs +import { Client, Postgresql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +await postgresql.update({ + databaseId: '<DATABASE_ID>', + networkIPAllowlist: ['203.0.113.0/24', '198.51.100.7'], +}); +``` +```server-deno +import { Client, Postgresql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +await postgresql.update({ + databaseId: '<DATABASE_ID>', + networkIPAllowlist: ['203.0.113.0/24', '198.51.100.7'], +}); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Postgresql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$postgresql = new Postgresql($client); + +$postgresql->update( + databaseId: '<DATABASE_ID>', + networkIPAllowlist: ['203.0.113.0/24', '198.51.100.7'], +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.postgresql import Postgresql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +postgresql = Postgresql(client) + +postgresql.update( + database_id='<DATABASE_ID>', + network_i_p_allowlist=['203.0.113.0/24', '198.51.100.7'], +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +postgresql = Postgresql.new(client) + +postgresql.update( + database_id: '<DATABASE_ID>', + network_i_p_allowlist: ['203.0.113.0/24', '198.51.100.7'], +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Postgresql postgresql = new Postgresql(client); + +await postgresql.Update( + databaseId: "<DATABASE_ID>", + networkIPAllowlist: new List<string> { "203.0.113.0/24", "198.51.100.7" } +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Postgresql postgresql = Postgresql(client); + +await postgresql.update( + databaseId: '<DATABASE_ID>', + networkIPAllowlist: ['203.0.113.0/24', '198.51.100.7'], +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Postgresql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val postgresql = Postgresql(client) + +postgresql.update( + databaseId = "<DATABASE_ID>", + networkIPAllowlist = listOf("203.0.113.0/24", "198.51.100.7"), +) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let postgresql = Postgresql(client) + +_ = try await postgresql.update( + databaseId: "<DATABASE_ID>", + networkIPAllowlist: ["203.0.113.0/24", "198.51.100.7"] +) +``` +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" + "github.com/appwrite/sdk-for-go/postgresql" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewPostgresql(client) + + _, err := service.Update( + "<DATABASE_ID>", + postgresql.WithUpdateNetworkIPAllowlist([]string{"203.0.113.0/24", "198.51.100.7"}), + ) + if err != nil { + panic(err) + } +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::postgresql::Postgresql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let postgresql = Postgresql::new(&client); + + postgresql.update("<DATABASE_ID>", None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None).await?; + + Ok(()) +} +``` +```bash +curl -X PATCH \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <API_KEY>" \ + -H "Content-Type: application/json" \ + -d '{ + "networkIPAllowlist": [ + "203.0.113.0/24", + "198.51.100.7" + ] + }' \ + https://<REGION>.cloud.appwrite.io/v1/postgresql/<DATABASE_ID> +``` +{% /multicode %} + +Rules: + +- Entries are IPv4 or IPv6 addresses or CIDR blocks, up to 100 entries per database. +- An empty allowlist means the database accepts connections from any address. +- The allowlist applies to the database and pooler ports. Appwrite's internal infrastructure, backups, monitoring, and replication, is unaffected. + +{% info title="Don't lock yourself out" %} +If you connect from networks with changing addresses (home ISPs, mobile networks, serverless platforms without static egress), an allowlist can block you. Add your serverless provider's egress ranges, or leave the allowlist empty and rely on strong credentials and rotation. +{% /info %} + +# Idle timeout {% #idle-timeout %} + +Connections that stay idle are closed by the edge proxy after `networkIdleTimeoutSeconds`, 900 seconds by default. Long-lived driver pools usually send periodic keepalives and are not affected. Raise the timeout if you hold connections open across long pauses; lower it to reclaim connection slots faster. + +{% multicode %} +```server-nodejs +import { Client, Postgresql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +await postgresql.update({ + databaseId: '<DATABASE_ID>', + networkIdleTimeoutSeconds: 900, +}); +``` +```server-deno +import { Client, Postgresql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +await postgresql.update({ + databaseId: '<DATABASE_ID>', + networkIdleTimeoutSeconds: 900, +}); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Postgresql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$postgresql = new Postgresql($client); + +$postgresql->update( + databaseId: '<DATABASE_ID>', + networkIdleTimeoutSeconds: 900, +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.postgresql import Postgresql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +postgresql = Postgresql(client) + +postgresql.update( + database_id='<DATABASE_ID>', + network_idle_timeout_seconds=900, +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +postgresql = Postgresql.new(client) + +postgresql.update( + database_id: '<DATABASE_ID>', + network_idle_timeout_seconds: 900, +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Postgresql postgresql = new Postgresql(client); + +await postgresql.Update( + databaseId: "<DATABASE_ID>", + networkIdleTimeoutSeconds: 900 +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Postgresql postgresql = Postgresql(client); + +await postgresql.update( + databaseId: '<DATABASE_ID>', + networkIdleTimeoutSeconds: 900, +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Postgresql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val postgresql = Postgresql(client) + +postgresql.update( + databaseId = "<DATABASE_ID>", + networkIdleTimeoutSeconds = 900, +) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let postgresql = Postgresql(client) + +_ = try await postgresql.update( + databaseId: "<DATABASE_ID>", + networkIdleTimeoutSeconds: 900 +) +``` +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" + "github.com/appwrite/sdk-for-go/postgresql" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewPostgresql(client) + + _, err := service.Update( + "<DATABASE_ID>", + postgresql.WithUpdateNetworkIdleTimeoutSeconds(900), + ) + if err != nil { + panic(err) + } +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::postgresql::Postgresql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let postgresql = Postgresql::new(&client); + + postgresql.update("<DATABASE_ID>", None, None, None, None, None, Some(900), None, None, None, None, None, None, None, None, None, None, None, None, None, None).await?; + + Ok(()) +} +``` +```bash +curl -X PATCH \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <API_KEY>" \ + -H "Content-Type: application/json" \ + -d '{ + "networkIdleTimeoutSeconds": 900 + }' \ + https://<REGION>.cloud.appwrite.io/v1/postgresql/<DATABASE_ID> +``` +{% /multicode %} + +The same setting is available in the Console under **Settings** > **Network**. + +# Locking down access {% #checklist %} + +For a production database: + +1. Set an IP allowlist covering only your application's egress addresses. +2. Rotate the [primary password](/docs/products/databases/postgresql/connections#rotate) on a schedule, and after anyone with access leaves your team. +3. Watch the [Connections tab](/docs/products/databases/postgresql/monitoring#connections) for unexpected clients. diff --git a/src/routes/docs/products/databases/postgresql/quick-start/+page.markdoc b/src/routes/docs/products/databases/postgresql/quick-start/+page.markdoc new file mode 100644 index 00000000000..0fb0c48570f --- /dev/null +++ b/src/routes/docs/products/databases/postgresql/quick-start/+page.markdoc @@ -0,0 +1,96 @@ +--- +layout: article +title: Quick start +description: Create your first native PostgreSQL database in the Appwrite Console, run your first queries in the SQL editor, and connect with psql. +--- + +You can create a PostgreSQL database and run your first query in a few minutes. + +# Create a database {% #create %} + +1. In your project, go to **Databases**. +2. Click **Create database**. +3. Give your database a name, and optionally a custom database ID. +4. Under **Choose database type**, select **PostgreSQL** from the **Native databases** group. + +{% only_dark %} +![Create database type selection](/images/docs/products/databases/postgresql/dark/create-database-type.avif) +{% /only_dark %} +{% only_light %} +![Create database type selection](/images/docs/products/databases/postgresql/create-database-type.avif) +{% /only_light %} + +5. Under **Specifications**, select your preferred tier. +6. Optionally configure **Read replicas** and **Point-in-time recovery (PITR)**. You can change both later. + +{% only_dark %} +![Database specifications](/images/docs/products/databases/postgresql/dark/create-database-specs.avif) +{% /only_dark %} +{% only_light %} +![Database specifications](/images/docs/products/databases/postgresql/create-database-specs.avif) +{% /only_light %} + +7. Review the database summary and click **Create database**. + +Your database starts provisioning and becomes ready shortly after. You land in the SQL editor once it is created. + +# Run your first queries {% #first-queries %} + +{% only_dark %} +![SQL editor](/images/docs/products/databases/postgresql/dark/sql-editor.avif) +{% /only_dark %} +{% only_light %} +![SQL editor](/images/docs/products/databases/postgresql/sql-editor.avif) +{% /only_light %} + +The **SQL editor** tab gives you an editor with formatting, query explain, and a results panel, without leaving the browser. + +Create a table, insert a row, and read it back: + +```sql +CREATE TABLE books ( + id SERIAL PRIMARY KEY, + title TEXT NOT NULL, + author TEXT NOT NULL +); + +INSERT INTO books (title, author) +VALUES ('The Hitchhiker''s Guide to the Galaxy', 'Douglas Adams'); + +SELECT * FROM books; +``` + +# Get your connection details {% #credentials %} + +To connect from outside the Console: + +1. Open your database and click **Credentials**. +2. The **Details** tab shows the host, port, username, password, and database name. +3. The **DSN**, **.env**, **Prisma**, **Drizzle**, and **psql** tabs have ready-made snippets for each workflow. + +# Connect with psql {% #psql %} + +Copy the command from the **psql** tab of the credentials dialog, or build it from the details: + +```bash +psql -h <host> -p 5432 -U admin -d <database> +``` + +Enter the password when prompted. You can run the same queries from your terminal that you ran in the SQL editor, or connect from your application with any PostgreSQL driver. See [Connections](/docs/products/databases/postgresql/connections) for driver examples. + +# Next steps {% #next-steps %} + +{% cards %} +{% cards_item href="/docs/products/databases/postgresql/connections" title="Connections" %} +Connect from your application with any PostgreSQL driver or ORM. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/extensions" title="Extensions" %} +Install PostgreSQL extensions like PostGIS and pgvector. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/backups" title="Backups" %} +Configure backup policies and point-in-time recovery. +{% /cards_item %} +{% cards_item href="/docs/products/databases/postgresql/monitoring" title="Monitoring" %} +Watch compute, connections, storage, and workload metrics live. +{% /cards_item %} +{% /cards %} diff --git a/src/routes/docs/products/databases/postgresql/scaling/+page.markdoc b/src/routes/docs/products/databases/postgresql/scaling/+page.markdoc new file mode 100644 index 00000000000..d3a39170fa1 --- /dev/null +++ b/src/routes/docs/products/databases/postgresql/scaling/+page.markdoc @@ -0,0 +1,658 @@ +--- +layout: article +title: Scaling +description: Resize the compute specification of your PostgreSQL database with zero downtime and grow storage automatically as your data grows. +--- + +Native databases scale in two dimensions: the compute specification (CPU, memory, and connection limit) and storage. Both can change after creation, without dump-and-restore migrations. + +# List available specifications {% #specifications %} + +Each database runs against a specification that defines its CPU, memory, included storage, and maximum connections. List the specifications available to your plan: + +{% multicode %} +```server-nodejs +import { Client, Postgresql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +const specifications = await postgresql.listSpecifications({ + +}); +``` +```server-deno +import { Client, Postgresql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +const specifications = await postgresql.listSpecifications({ + +}); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Postgresql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$postgresql = new Postgresql($client); + +$specifications = $postgresql->listSpecifications( + +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.postgresql import Postgresql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +postgresql = Postgresql(client) + +specifications = postgresql.list_specifications( + +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +postgresql = Postgresql.new(client) + +specifications = postgresql.list_specifications( + +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Postgresql postgresql = new Postgresql(client); + +var specifications = await postgresql.ListSpecifications( + +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Postgresql postgresql = Postgresql(client); + +final specifications = await postgresql.listSpecifications( + +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Postgresql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val postgresql = Postgresql(client) + +val specifications = postgresql.listSpecifications( + +) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let postgresql = Postgresql(client) + +let specifications = try await postgresql.listSpecifications( + +) +``` +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewPostgresql(client) + + result, err := service.ListSpecifications() + if err != nil { + panic(err) + } + _ = result +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::postgresql::Postgresql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let postgresql = Postgresql::new(&client); + + let specifications = postgresql.list_specifications().await?; + + Ok(()) +} +``` +```bash +curl -X GET \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <API_KEY>" \ + https://<REGION>.cloud.appwrite.io/v1/postgresql/specifications +``` +{% /multicode %} + +# Change the compute specification {% #resize %} + +{% only_dark %} +![Compute tier settings](/images/docs/products/databases/postgresql/dark/settings-compute-tier.avif) +{% /only_dark %} +{% only_light %} +![Compute tier settings](/images/docs/products/databases/postgresql/settings-compute-tier.avif) +{% /only_light %} + +To resize in the Console, open your database, go to **Settings** > **Compute**, and select the new tier. + +From the API, pass the new specification ID: + +{% multicode %} +```server-nodejs +import { Client, Postgresql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +await postgresql.update({ + databaseId: '<DATABASE_ID>', + specification: '<SPECIFICATION>', +}); +``` +```server-deno +import { Client, Postgresql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +await postgresql.update({ + databaseId: '<DATABASE_ID>', + specification: '<SPECIFICATION>', +}); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Postgresql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$postgresql = new Postgresql($client); + +$postgresql->update( + databaseId: '<DATABASE_ID>', + specification: '<SPECIFICATION>', +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.postgresql import Postgresql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +postgresql = Postgresql(client) + +postgresql.update( + database_id='<DATABASE_ID>', + specification='<SPECIFICATION>', +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +postgresql = Postgresql.new(client) + +postgresql.update( + database_id: '<DATABASE_ID>', + specification: '<SPECIFICATION>', +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Postgresql postgresql = new Postgresql(client); + +await postgresql.Update( + databaseId: "<DATABASE_ID>", + specification: "<SPECIFICATION>" +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Postgresql postgresql = Postgresql(client); + +await postgresql.update( + databaseId: '<DATABASE_ID>', + specification: '<SPECIFICATION>', +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Postgresql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val postgresql = Postgresql(client) + +postgresql.update( + databaseId = "<DATABASE_ID>", + specification = "<SPECIFICATION>", +) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let postgresql = Postgresql(client) + +_ = try await postgresql.update( + databaseId: "<DATABASE_ID>", + specification: "<SPECIFICATION>" +) +``` +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" + "github.com/appwrite/sdk-for-go/postgresql" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewPostgresql(client) + + _, err := service.Update( + "<DATABASE_ID>", + postgresql.WithUpdateSpecification("<SPECIFICATION>"), + ) + if err != nil { + panic(err) + } +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::postgresql::Postgresql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let postgresql = Postgresql::new(&client); + + postgresql.update("<DATABASE_ID>", None, None, Some("<SPECIFICATION>"), None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None).await?; + + Ok(()) +} +``` +```bash +curl -X PATCH \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <API_KEY>" \ + -H "Content-Type: application/json" \ + -d '{ + "specification": "<SPECIFICATION>" + }' \ + https://<REGION>.cloud.appwrite.io/v1/postgresql/<DATABASE_ID> +``` +{% /multicode %} + +Resizes apply with zero downtime through a rolling cutover: a new instance is provisioned on the target specification, data is streamed over, and traffic cuts over once it has caught up. The database status shows `scaling` while the resize is in progress. + +# Storage {% #storage %} + +Each specification includes a storage allowance, and storage beyond the allowance is billed per GB. Storage only grows; you cannot shrink a database's storage after it has expanded. To reclaim a smaller footprint, restore a [backup](/docs/products/databases/postgresql/backups) into a new database. + +# Storage autoscaling {% #autoscaling %} + +With storage autoscaling enabled, Appwrite grows the storage automatically when usage crosses a threshold, so the database never hits a full disk. Configure it under **Settings** > **Storage** in the Console, or through the API: + +{% multicode %} +```server-nodejs +import { Client, Postgresql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +await postgresql.update({ + databaseId: '<DATABASE_ID>', + storageAutoscaling: true, + storageAutoscalingThresholdPercent: 85, + storageAutoscalingMaxGb: 500, +}); +``` +```server-deno +import { Client, Postgresql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const postgresql = new Postgresql(client); + +await postgresql.update({ + databaseId: '<DATABASE_ID>', + storageAutoscaling: true, + storageAutoscalingThresholdPercent: 85, + storageAutoscalingMaxGb: 500, +}); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Postgresql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$postgresql = new Postgresql($client); + +$postgresql->update( + databaseId: '<DATABASE_ID>', + storageAutoscaling: true, + storageAutoscalingThresholdPercent: 85, + storageAutoscalingMaxGb: 500, +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.postgresql import Postgresql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +postgresql = Postgresql(client) + +postgresql.update( + database_id='<DATABASE_ID>', + storage_autoscaling=True, + storage_autoscaling_threshold_percent=85, + storage_autoscaling_max_gb=500, +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +postgresql = Postgresql.new(client) + +postgresql.update( + database_id: '<DATABASE_ID>', + storage_autoscaling: true, + storage_autoscaling_threshold_percent: 85, + storage_autoscaling_max_gb: 500, +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Postgresql postgresql = new Postgresql(client); + +await postgresql.Update( + databaseId: "<DATABASE_ID>", + storageAutoscaling: true, + storageAutoscalingThresholdPercent: 85, + storageAutoscalingMaxGb: 500 +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Postgresql postgresql = Postgresql(client); + +await postgresql.update( + databaseId: '<DATABASE_ID>', + storageAutoscaling: true, + storageAutoscalingThresholdPercent: 85, + storageAutoscalingMaxGb: 500, +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Postgresql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val postgresql = Postgresql(client) + +postgresql.update( + databaseId = "<DATABASE_ID>", + storageAutoscaling = true, + storageAutoscalingThresholdPercent = 85, + storageAutoscalingMaxGb = 500, +) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let postgresql = Postgresql(client) + +_ = try await postgresql.update( + databaseId: "<DATABASE_ID>", + storageAutoscaling: true, + storageAutoscalingThresholdPercent: 85, + storageAutoscalingMaxGb: 500 +) +``` +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" + "github.com/appwrite/sdk-for-go/postgresql" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewPostgresql(client) + + _, err := service.Update( + "<DATABASE_ID>", + postgresql.WithUpdateStorageAutoscaling(true), + postgresql.WithUpdateStorageAutoscalingThresholdPercent(85), + postgresql.WithUpdateStorageAutoscalingMaxGb(500), + ) + if err != nil { + panic(err) + } +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::postgresql::Postgresql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let postgresql = Postgresql::new(&client); + + postgresql.update("<DATABASE_ID>", None, None, None, None, None, None, None, None, None, None, Some(true), Some(85), Some(500), None, None, None, None, None, None, None).await?; + + Ok(()) +} +``` +```bash +curl -X PATCH \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <API_KEY>" \ + -H "Content-Type: application/json" \ + -d '{ + "storageAutoscaling": true, + "storageAutoscalingThresholdPercent": 85, + "storageAutoscalingMaxGb": 500 + }' \ + https://<REGION>.cloud.appwrite.io/v1/postgresql/<DATABASE_ID> +``` +{% /multicode %} + +| Parameter | Range | Description | +|---------------------------------------|--------------------|-----------------------------------------------------------| +| `storageAutoscaling` | boolean | Enable automatic storage growth | +| `storageAutoscalingThresholdPercent` | 50 - 95 | Usage percentage that triggers an expansion (default 85) | +| `storageAutoscalingMaxGb` | integer, 0 = no cap | Upper bound for automatic growth | + +Set a cap if you want a hard ceiling on storage cost; without one, autoscaling grows storage as needed and the overage is billed per GB. + +# Picking a specification {% #picking %} + +Guidelines for choosing a starting tier: + +- **Connections**: count the maximum concurrent connections your application opens, including all replicas of your app server. If it exceeds the specification's connection cap, either move up a tier or put the [connection pooler](/docs/products/databases/postgresql/connection-pooling) in front. +- **Memory**: PostgreSQL performs best when the working set fits in memory. Watch the cache hit ratio in the [Monitor tab](/docs/products/databases/postgresql/monitoring); a sustained ratio below ~99% for an OLTP workload is a sign to add memory. +- **CPU**: sustained CPU above 70-80% at normal load leaves no headroom for spikes, migrations, or backups. + +Start small and resize up when the metrics say so; resizes are online, so there is no penalty for growing later. diff --git a/static/images/docs/products/databases/postgresql/connections.avif b/static/images/docs/products/databases/postgresql/connections.avif new file mode 100644 index 0000000000000000000000000000000000000000..548756f3684a49227e5a0031985a397c7c3291a0 GIT binary patch literal 33091 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 Y9u^%^Q0^`Qh!db*5P54aMPos7P(RS`;s5{u literal 0 HcmV?d00001 diff --git a/static/images/docs/products/databases/postgresql/create-database-specs.avif b/static/images/docs/products/databases/postgresql/create-database-specs.avif new file mode 100644 index 0000000000000000000000000000000000000000..e01987bf2ac8865032d674a103e3eca22b719b9b GIT binary patch literal 32500 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 z%0D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 Y6Nb{}p9h!c?TTO_!>e^P5PQAvC~Vu1ApigX literal 0 HcmV?d00001 diff --git a/static/images/docs/products/databases/postgresql/create-database-type.avif b/static/images/docs/products/databases/postgresql/create-database-type.avif new file mode 100644 index 0000000000000000000000000000000000000000..6b2619635b05b1da538b33c7b19ab2e9eb0ebb01 GIT binary patch literal 38925 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 VEQSWyd=f>;sL781>k9$(_bIIUj&J|~ literal 0 HcmV?d00001 diff --git a/static/images/docs/products/databases/postgresql/credentials.avif b/static/images/docs/products/databases/postgresql/credentials.avif new file mode 100644 index 0000000000000000000000000000000000000000..0f77e9949acbf1296d15071a61509cfc632b9962 GIT binary patch literal 16596 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 HeYYm1c~JXr literal 0 HcmV?d00001 diff --git a/static/images/docs/products/databases/postgresql/dark/connections.avif b/static/images/docs/products/databases/postgresql/dark/connections.avif new file mode 100644 index 0000000000000000000000000000000000000000..1713ab1916a8bdd0513858352fa8fe53c302b16b GIT binary patch literal 36103 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 U?n|Tzrmrq}0I{{IZuNwntlPHSPXGV_ literal 0 HcmV?d00001 diff --git a/static/images/docs/products/databases/postgresql/dark/create-database-specs.avif b/static/images/docs/products/databases/postgresql/dark/create-database-specs.avif new file mode 100644 index 0000000000000000000000000000000000000000..c3702ef2ea301ff4d8d192e884713b133ae83937 GIT binary patch literal 34502 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 N)PX-^6jDRWwT!fsko*7u literal 0 HcmV?d00001 diff --git a/static/images/docs/products/databases/postgresql/dark/create-database-type.avif b/static/images/docs/products/databases/postgresql/dark/create-database-type.avif new file mode 100644 index 0000000000000000000000000000000000000000..ddee81190acd4e0b3ebdb802246a51204a435792 GIT binary patch literal 42082 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 literal 0 HcmV?d00001 diff --git a/static/images/docs/products/databases/postgresql/dark/credentials.avif b/static/images/docs/products/databases/postgresql/dark/credentials.avif new file mode 100644 index 0000000000000000000000000000000000000000..4c47e9f18a56c955c0d1259ca9e0663b02082943 GIT binary patch literal 16894 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 literal 0 HcmV?d00001 diff --git a/static/images/docs/products/databases/postgresql/dark/monitor.avif b/static/images/docs/products/databases/postgresql/dark/monitor.avif new file mode 100644 index 0000000000000000000000000000000000000000..01261934f13353ecedbf610b42025ef53d22da34 GIT binary patch literal 48949 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∾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 UZy>4RqOz*=UlpiHoU6~uK;m2%Bme*a literal 0 HcmV?d00001 diff --git a/static/images/docs/products/databases/postgresql/dark/roles-tab.avif b/static/images/docs/products/databases/postgresql/dark/roles-tab.avif new file mode 100644 index 0000000000000000000000000000000000000000..0fe6284c6e078ecd497f19236b8cefb097bf461a GIT binary patch literal 28297 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 HTzl+bAPUZe literal 0 HcmV?d00001 diff --git a/static/images/docs/products/databases/postgresql/dark/settings-compute-tier.avif b/static/images/docs/products/databases/postgresql/dark/settings-compute-tier.avif new file mode 100644 index 0000000000000000000000000000000000000000..105cb23e159154f7b38a3937f4030cc0da3267fa GIT binary patch literal 43887 zcmXu~V~{Y+&NYmVZQHhO+qP}nwr$(CZQC=~*yeZd=bSfPot2eJRp(b%r&9p{0KhSG z@pLeBvor(vPi!sC82@M6S{nY3ui2Wq82-=ypAcG@*f{<FOaK4}OJkS+Xa7HhbFg%= z{XYWupC+=ju{Zu76A=Ia{BQkFKL7s+Q04j`Bet}(`@ci~&x`sWF$MZx)PJ#tZVZh7 zGu12|oE-i`4oe4P`~MKe(2Y?zko5n;P%NDtO#c@I008>m23q`2AvjoiSpLrg3;_Z0 zAD~$}*#5u#|4RZm5C|9mpvu?Q#Lxu^01ArJ%KWEr2nY+7fa!PzNL-Kx06_pm0U(h0 z1BSIuv2?)YRd{qyw3NJwhzIpK=R8b9p;+V<r>{<avWRWYdBQy>r(kVs#MLOmwYzl` zN$MIHvw^DiYYb1Qd(SbZM|N)ULjz7>T6OWfW(V^cCrcGYC8Rzdrq(0neH`q%3U?P~ zPCsl#C%5XOk07#{fCS0ti}d}Qi1&VMie9Alq|IEM4g3dz7~!(eg2;U+fspI-NqkEb z#35bGMNvz{*YJfDa<dqzv<^_ppzu%%k>}+t15bG-Q49mkNu;RLEt<=;0`Xj;asx&D zojIEr)G3DT79_^f<@{(miLN@jE6!!kMuR`<0(Wtqb1H|+B<B!h198833hveC3T}0{ z_E!)mf7fEdMF*jpk&X#!I8Wy>wlkEQ6q84t=jqpqDqQ(OQtHf_;lB7Ey?!qtl!q*D zAe9et7tEEg64EJ&`JzfHuN{=6h(u!Ev42|t1_IhSXeAhb$b#s<HB87Orpr+1l1Ogh zcXCOqc-(jg7Nr;x3v1S600s9yeIVFO%4Thqnm}EfzIPY~6dlQb5WdpR`we6R41}}M zj)A7r%)Pm#o@I{<n9dpa1g7(!wwLW!!EtJ;Ng?;;dcEbK;nX^-yk->`GQ1*I;p8_! z#YK+bNwYhq?4>dLNVGc_;lIuFeWwK1W)J)T$)9gVwU%lo?azW!81t(vL?c^P3%i># zikLvhqm|(>NC&9gu$VQd<n~qIDp+hYeH~z_-^^J!2(JV)V_VlRb%%lub-FN~dm!5D z$%B<E_8|+96a@#V&eK(g%&_*~Cw#s4NM(hxZ<DGvzfs2o8*|Y8qWsn@GTh{EXeIie zdB~tKEcp+t1f!EPeGK(p6%Lg`ZJNWoSntK;<^s-qgc-Z_g{8U_d+DozZ#M5@hK~rD zKc7G^*_xK-dfzXfa)3fYA&o6=;l?XhFhJDW(fw_I7+|ziZv=#FNz_&Z3|WsuMP!mw zGIXDDGbsQQzgZ|;0v8%GIKIM9nXZ5eYSrLU`&1l0ch}2{L`JzPZv*n|M&N(t_JqfA z1zN!iY2@;yv|U^#28BJwr~_$0kx=3!)q%qI{fl}kUe)^}UnCb(J^^cu1qIMBo|R-n zqa%#4V!q?kNZ3+Qn#f;)TF2w!h)ZBtwTB(&usIwY*^e|<QGTQxgXp(|++kJqr-jh* z$ri&8q*PMD3@Miu2$3|tBB3^NL%&g}?XNx>fi{n}r8QpszrIC<_jMmQczky<P@EX) zW&-EV+N0Cv&JnrXcich}DyH_8H*NHladx(%(AX2I;`Js?wpX$ZGu*6Pu%!Ox+!J@V zofPd+bel-ddy1U%2-Y?vmb3oi#CZ<sCPGlG1if+~j#-EbhjeX+P+*Qv2$w7>H^J`y zar~%EwFem1lLT-zoKb-T2p@QC-;f)B%pqUU;yBK6%S^qOJ2RM@hi%O}6!pjlN0tSV zX<Y8pZ~%VjvMIr`Eoz9Kw2^B0MghA$u9Ev{U;H}*ku<mUzD%5tl!9&QtDu3_v^c`S znmrQ-hKTEV59@2Ool1IF<=@CG;Z3&`o>b>Fvu*bhh!N$U+ssWEvL1P-J^R(=pGO7G z3@}#Zo<T(?<>-0>it-Y*C}n>)tq2hwr$0#=b78=Ip#xDF9T?3C_)z;R!yj9TXlBV2 zq3rgdIS$Z;J5b7a+5hA{kXbW}CSlm$xomGjuLIiVJ9jd>_t*H-p2n3c!r$l8-LU6S zKTsy?Pf?7Rb&X3IV#bIj%k8(umlLiRV3hjQ7V>k$pTyF7#rZi`x>=d5*Tlz}EZ&1q zR-SjWu8BHWDj(&wq=GLoCu%cL1G*-nT0-swtK(sWAkdxwGd0O5E~!qJo8i>=94BFw zHKSufnv70TjiPkXnm2ft$J_mekBzwtm0fw5Opw=0W=ckG9r06gDsk<V36iRGkOb)` z1Wnacu=Uh(MpgK5BH?zzs}OKR9vXk8UNk?N$NNVcT2cLBh`;LpJt1bh9rc<X!M%n$ zV7p-a3cs5o&@N*bN7|kKB1%0kTWkco`A`fbqv(UFY8#>hD4x63MqCrqO6<~2f;Jyb zw=pqc-gorl9NP%%#azKu+&CdtCKloE@3bM@=^g>fOVhMd?6QPcS}aVj^|dUVo;N_8 z(funF!_u~H`jjsJ;_AUOJw+S$0Gaqjq$l$T`Ne#$wOn2GV47NL!cO9Y2rX+iNCK1d zmdAawbcw}Mu$t^(NsV;?sq6dBKLB%P)^uc*7T9|J2pR}UIhdTIt3MB1vlE#Xwi%0> z8<);clIU&Kw02QI6n^R>o$ppZ$)86%iK3I>o`Sor9=4S+MlmqwUl?UoAsF<#1)=Ry z7KHqWuq;Pr=`YZU4q-tgzIoH$#AqD9^>6zGRC<On7aBif5NSt#NAVQn1@xhoic3fI zx$g-;0%!86O0-lIyie0cIncAGZ%u;Qn}COoblWSm73Rj;X(7JZVvMZR@FJqCrk-ca zJG5B2(%da}BUT7ZW#mgZXdwadjhpvvbi`u!P9ksB;=YW2+yw1oixc^$n)P?j!gTVJ zykueR8s&o;Zu61LALHsWC0nh+0D7HztB`kMuoH&{$^l#>533P?W_=aNJ{W%6s(M)m zOx_Uc(YyVMP0*i9(G!G8p$PDLZEy{Oz&7g?lah7KA-kyGdIuU>rd>%Gd2<h@E6K0E zMw2-J0d(09845qJ!^KTH17~hDU7Y*MZ=4Ph7+tDvkK?WKeNeozXF6H}mdQaf%i?9k zkgHD_Btiv#GCqUi=!w6JDkkaiBUcL5n8X!%lKaks?&OumnBRMo+kqVuCh=hkO#&-e zH0V`y@HdtP*Hk1gm?&cRq^ZPjAPy|HReDPK;hJ6ngaxhY{p`K>LcQ-`1`ui)jzoCp zxi8Hp#yQ+D(#FH!&5!>Fi?|_3r{-MX_$!OFH?rLGE#_b>jcFpBi6uM$Y>ZSFQKxXF zfNT6kQ|uM(wGCat!Q6Yuonv({+r4DduY&KIBD@l8pZbB>%ULZ1j$YWeeU)`l_%0lj z#gW*TwO>ssb#;q3$F)IlM4y)mL?u*%C5yY}PkC2A1lEUksU1D3smAj1m_GCC^~A67 zV11IXbJUo6zek3!Z!QPkZcYdc;8xiyfiB%f?3NzZZ@ki8a|1P|Aq@i+j~733)L|1t z$-G>_@z3YXyPpKM?2`lm%OUPtE^kL*Vmpa)6TCdl#lnvCq8|iQyJ5YT?%8l+QJa*$ z!f@EjpV~;6PWVGy9vR~)#DEXH!-lj!qaf2-MW}~@PYo(jkN!bctol2-?~W+hBXZmL z?{FJKFz1v!d5!8hHH>e!eG_m*e=ec;hKhf`G-i$H?zO5OYlB60S3c-0JTTATP^Vu; zixlb5>-h>svK!%Z2_a-~B;#sCSQ@}x0V{nDdQ*8*dGVd%jC08hx-6fHI3WzQEYG&1 zXR6a|YpPPmwb<)EAKZwyGQS<lRRWHnfP7&2EP6Jkc3(|o6~2vY9(x@of>29ZE|Ef~ z_2>d}g<G&Y6(m~e()(wKy0V^82W@S0X1Alt!B9j9QVF)ayyppl)K(OuAUuzrsB@fJ z>W%E>I0UQNak{Zp7_UuvFr09Ql7nr8+Nj-`m@0w}H-XWib1<F%ARlu0u&MW0(QwuB zO|8zw7xzK(ps*2bD(C<TRe(z}8eJuMRAWyM9RI6snI1k!Ik$Ig>AW1$M9>dP(okf; zEiHoC6_^8YGQmSAggP~anu)ta0+p9qdI~sQcA4n<u<`;JKReS0<Zf)6sU0{Zd<qB1 z0?s^rPcmt1^`kll$#sF9Ru^!`V|e)i@_}qkqoRQ%9j_|=2lI|8dztSbQyV$fL&s0B z5p+asZRbD^Lzh#Yw=b02!h`fek#Ts{k7URfVka1)T;%aRx!{pee^K>9p?F&)e|NOM zwl;?roDAlr8Gmdw+t3~m7Gq<B9e!Y2oAUlkJsU5KFuKdjsX1dvq`M=s6rrp&6_<k> z*PX)H(=AzV=#PT5E?RTUaAREP+dAnpE~n8Z`&-$5COkvd4BZB1mE!8~@zOvHdjWFT z9Fk6BIUq4|Iye@Sk8(bz079?{Um8}`L*kxK(oe#-aSQd~jy^MdVZStAc~l!-%B4+S zOvms}c+67(HZrl*tSTrb--e7}MW(_3wL1lmP}OEH=2E|UW!tp7orJ2Sn$={Oc(|}{ z-WFmZNwQPakvKE6?LoExxs&o755!+V^wk3X!wn-f;_@^y3*BWWj1hUx#Tt~LIROtC zqFNuElWTF5#OUawf=6)m$*JmtXCd7GY6k^k-(`#7!gYo9=sG2?UQX+->*x<f1j8R0 z={w^lLW?TjQwk4VEY=_M*_Jfty@pU%e_i_6NMyQnSkrVf3E*||XJ6^`QM^)akpMc^ z@qO0S9DJrQ^_SRj0^?pg($E}*^sFnkOd+Ffp#o|puiY*N9IAVM<8e7eeeB|bCwho( z?IvjCL+l=O*D;M_VlHilG~WiIj{&Hgx3-6xq^r2x@Dj@v<yZoF&hLdq`aGKoZ^5#h z!?Sf@29-Nhow;g!)_L3+UovqgvP>Vi&MIlAx|wh7C`}EQS3ZmjgR1uoNMl+ZFvOC& z3>_ONF2Tlk!lKDs4cQLc&Gf$)d^rbXO9@D{0+8dVvMw;WAg!Fbrrq!r9}_tBAj|Ao z6Xezw(8d>CN12`t&V-XxdOIs3qq{%}8^vt@Ksc~*Z}(iP$qD`^h@N>kg#bQxc0gFm z(1d~0&gSCW-lv(+kJ8y<5OY8tow*TOZ(6hjXAMEIfDLrxCGzg?+GhFRkcY|e4beQI zj*2a3{a)-9Kkw3=^|jISlz0t!Sxq_JfD@u|mkW)}{_Nvn;~3Fs<MSKB;*;_%I4(|s zw~x}ct~uWbPv$^OgNy-}Z?+9`g0Te5dcYpLl24JLxaxnEZGn#F_RP^I-3{z*RT~6i z0WbhMkBpP=f?WHSAkm8br|vnLGC?vM$Y~wgAAyTa!0KK#>tqrUZOIpp+k1(U)f^Vs z&J+>jn;9_HsF$Ct*o39!aZ>5+4rL-mwlFi-IQYOr@Ut{@!4(tb(So_Uc#dw2g^s&g zm>pA>I)O}iop9?CEq}SxRhUWDd+3lBt_Vzs_gV>j7dyIdzk~mykDZi7g7AYuHL3>t zZA+=Le+Jfqj|1@~EF`Pb2HwJbo;ikQcO~W0B5Lc5aPT<y5d-S6(s;+FV?*l~Y5xW8 z@<bCNf2Es9lrG!b{wWLNfi_!h3wT$FjqfPL3_$IhQS<P?i{oXvbMbjPx{obr!R)!g z^E7@}eFrhG1c>rhJLA5I5ckmJP_`F-cuCb#LOFl^PQc&i?AQnAFpvb6AEH@$jrd_3 z>eor4_c;Ky50zF3dPSASOSuIxEKQ+U#b4=1PA2}Iu<oaVq<Y4>t?tSZmjh5_y&^VR zepHwdeEw6AOjc`xvuRnpJH0@HR|Fo#g?n`Zi^O~+Al`x_ARXr)w^oM-05$@RYAvhy zX>Iy~9TQ=kd#b9#eGj>FY2EyQ=VnkaCrABZ3X}_btnWisanEIEc)e2T2L9x}CUx7C z3(s3AX0PO@N7P<EC+0}w?IBhAv12Q{^Ivb;D0VzG&TsYG)mL{sp~Ygj0q5n{i#BkJ zK{$kkjT|egjn&OR^CtCq(F_QU5ARh>-4)Jo9}Cxmjf+01C|Pge27wNPqr+;9ZS?kX z9`8G<LxDAhi=?MVU5f;+i*!?@$elq$N}j?}1m_!sWp{}5A7l(G?Tfu{hkB0DQ=5_9 zYXls)!6Rjw3GB%^VT{v$Wr51<W7LtY8EsVwOVysFdQJw8Hbn>HuKr@t;4N^A{YUBx zL@_+BnbpK0E*i3KWyc-9U_!5n`EXnmt<nce!PLl1v$S^5#_OZP;VY5`7J1<w2M+|6 zL*iknWXb8eGu1Is0K+jQYCNm?(SAAhb9PAqV5{~~o;L?YU6wrcr2$waHr4*fD2))O zN6TkZ3F5*bkZ7Lkca@E;g8}#jz7~1Uwjr|p4Q*fp(E2d2irR_Xp;MzE^ncdf%C<oy zM&w;(L%6ncF~GDk%nk%-9((~U06M{K*tEMl9ZDUAg=6I&2u~%;j@JfDiye-~{3)ge zdcj7>eH(AH!hAENAhI93W7^whY$26sEgc=7GvZ$nJEa$^T0bMIM`62Bpcc4b2({Hi zB?ma75Y|J^yxnYcK|nVjq_^r$Qx0L!1fkg_T&t>(NQz!X#Ym_Qo8q!+=*qPj&oMUs za{$9;%L^*E%sq6ZwM*Hus9ESGOaKT^NE4=nWO0h3^F;Mso_dBVBGyG(!Y)|_sR6^q z22_%H9p0wu)BeGp;CKp#wbS!0q2RREG7x>}Iq#2dYjdT<7<EthYlf%Ab%-8Yqcdbz zf@E|)1&kxk_5=3phHg;)3dd+qr&nhqCCmlDs?K#D5}yfVnyuu2kRmGR#rw9m11jEd z_fT;q(YBuBm+C3>6&+@QZ+x4y7ahm!<W4w#XOPcy2)VA{^oe8<ft?kD5DCk)S(lOt zsk`}7hk|bJv1}?4+v4vZK_4meWioVstS0jAaVw+zJDfKz1f8L6<Yo{Ng=lUeFXR#h zRn?uqOUSh<N+I~@bTf;&xilZO_YqGro)il>>)tic2>WKkr<>V|iuCqg{BId6(-A=r zUiTfC1I-AS@HW9QtHolIG>F!>Wk_lmhV~=)MXJl4RU={A@rO;pR<zGfaQ=>Mqy4)A za}x+QeV0g?zvaI8sITdYUGBc?dT)M!#=r8|iOK%}XY=MfI*?F5%{Tco!7krO!b>Ey zy!8Gd$1tNk7_O5IUVn7(U;YJ^hf&+I0I{vGIlQo<tGS$vK>R}-me-<BbeR7l2YC&@ z8w@w)STU<4^n%_|x{OeVq$$y5JXmiAGjMv5!~^G_EWPHYNGd>X`CUr(qz8R9H#dS= zzek+ykKv@lY~u>DJpN7Tw0N3VHMP&Dew*paW@M3H@1Z75eoX-}yxu%SRIOkhCCZjZ z?CKTJK7*QF_UQP+7^7RKU&=J&s4~EU{K`ms?5WGC>XKi9-zb1iMy}e%74%Pbq^d?k zQc2BM+g&_8t)pszYgDs!#yT1U>~%hp6;!h`vN2%7S}}&_EFmQ?)%p6!v9D(!r)3>& zT~B{$BAAzBOXcpHO8}2^`+l~x<i2<|q)-JPqTLl^$(6*q29eO6Gl#?LfGFen3J7Hs zvr-4k(^mxtloeKR1em9{Jv@HN^jD$Q!Hd0*7c=qF#z!gY*uIlsl&KL!GijC=y7y(j z5wj!N?bKqJ-70o7HjId5iaay~VOv(GABIkO>f`snw>n@0a<AD$-NY9T{C8PvR<J%` zCP_6QbnUH5>am3(MF3ntG*kE}GZa17$O#n&KA1uzYB6@yUqkh6Q+1%Okz%<e)6NOF zzU?2MtNY<IH3lo0#^9wqvh>#OHjH#XS;O$}7bt1fu5;Z~ME@=Og&aCkYb`CvY*X}d zF@kf4PbTSI973xUjbu515%0?Wmi7{5(N76+d&~raAjc!ur+WrZlqpI;&1S~bNSn>K z=5RI9ZgBLM_~MXyh!SjxvWv`+H%5>U)}5G1ZqI#1t`h=R6CaYFU%><I6U$cR=dK*a zPrD4Ye5F%`Gd_rmjABr_s?(e}w>y9zw`LK8ejBBeSTQvxcIy$N@lLk+T)4J-ZboJ_ z%&oPzT$G}-aWPUP!Rg8+w#9*^(FD2}<uKRX6{wh&cwvME=F*_1OSHPqBid)Fp|qMC z()N;2q+Rx#^zs3F;~+KTU!}fjEjw|EvoagTIa`pTc7n3Ay;uTgg@%^$`KHVFf_m&) z7bKfY;{iavhrm%hzr`)%d-5sga|RS&JVaPJn(C-;2*^x4d9iYK^yr{Tx<KN|ula9f z=TKGcPv&BB)H<3`QRtZeF=nmqD>>TZTQ8_u5%iZesY4*+(yLN7w}L6x9|_8N$-9yn z)ds6AAt(br3~<*yjzB3PgKqUBYTLjkCiOss(-fhTyYLibR6>Was0v=oBp}mRRl3X5 zRT+uq_nu#Zcxx$Gk&@NNo&oQ&oxuQS5NcBcp<r{fq3&8=GJD)Ow2&q3eaOR+<#)s5 z+rUG4s6ibGK)M-P*@Fk%=~``1XHSqZHd6U;PTA^1hW)x6-{h`wf!@oq>SL|Mery!o zGdE)Kmfw@J%2Im@<orX^{xLyj<+sQ;pwQaKOYErQ4~T)9VC;?k9Gg^AAu$RwRsM0- z_kcEBRZ<DhRUX5dBOe^{tF|nXvol@z32lTy0|9&s|9i6|91CWAFBdt9*KVq^jeVet z@NF(UHlhnO%vb#O(8;F&28L%BN*LwAE!Z65I_#m2GskZywGO5YFFp6skH*QN&vEev z`pQHCgD&HF(|)6);L0VS)N&2G4~8@eW*(;7?v-afaWHl6n%UjL6D%%U%90j_gutZE zqJxI4Y^h<vl_TP9ucRV5`Qot&!46A;na-sxP1e9U@g}Qbs#qV5<85p+-pK0-Tpq;I zr2vONqWIL=!qFGC4`q;)b;%MloEWa{zjEVm=_hm_K1*-9nY@R?pda6d|EkfgcPRyQ z5nJ0p09s-bh1@r%-(6vp5dy)59F==L(fN6W%n0%6NAHd@t0a5R0B{f?$GpH)9D6oc zrPBVjJiHh$g$#CI;O5a;jQiXcPm2)ZQbx%FH<452@*V+5t|_qz_qBLi)`R?Ld;1h^ zH8YP3j76n0?=`~VUvlJ1wIUWW895_Z*P<8;REmgCWdxR*X_=A^E0~Y@CxS>#S}G7< zG2|%tB&gg}VF7VFI7t#DK3BC56S9Gh_h;jEz14SOyg9-1j6J9hl7Bc%s7T1xB-H;% z1^1sNh5shoj^ZXB9jnkTs_||@jUib<xYDILhSM7OHK3cui4kri=;%$ee#*#X=jI=) zoMp}ksf^?0SDxYjr3-AL{W)2*_UJTtamp=|*EIX6DAa3Ivw`_`C#R242x>tN^$e*h z;IDlg$iRidj%-d%m*rr2$xDR${j1qnVC$FXoJnpOCzSyadGv8wY0(Ou;%-2a@S;_^ zxMETkH${b!HQ{Q@5G@*gz`fHQOkd87n_9a4xDjn=d`X8%yjCCK9puKyorhL>>Rysz zQ1e2F<ZJ;8yaPsePmx^TfB{Nr_@YV6Gz=kZpt4*g{Y3cJ_|1h&-XU$R6qUcH->_pU zdjh{&KSsib(WYjz8N!b1Exjs?O?u<6wMbXcRzmW1|EZK|5a!7u$meph1S_T%+(#HE zdp$fy)m7UIHDfuSc}YluNYDiFRtRg|a%vR|?UY&mrMF4YMHQ=)J8RlEG*c~Ogz~VF z2N;3ko45?gd_^4Sy}mo~E;AXR-ZV(JXX0GA_ftbQ^GfRp$3ho-JYb?w%i*EGBqxvo zxt~YN6GaXrgpu98D_*oXPuj-EybB|xsY_^mbL(^uz^xxY(zbc(SSrl5s_hWaIXyPk zE|%L9i1!B_p+=r`JD52&;K5BF7lf36&fo_T-s4!}4DT~m(B$>p==XVI6!Tam&=`(o zFp-~B90X$nR?yQ0op*kkwpLa=$J}@;m%r-uUeY(A<_L`eeFB!E`2@p$@$RBmHE%A5 zW?(C`7$Pzfm}Vf9?<9-B`D_SraETaZ8kFcW1(N;Brvd3kBfN2X1SVnI3km}-2o4xA zL*TP^Zv57ew>GNHA{y0xS5@PJLz|=Y(^z)L>PajbY;=IylE?+YLB)owwhJf-K3mwj zOh0JG*Q;rVcNGH2`p$Vl$^Q3K;qI+e7Xt9M79Uo0!Ka_<DW$)G6+1k~9RO0sGDVZV zksxgBu9gou3BNPXxcL3}dSt<ppdAE=IUA-ml0OEZA<~I5J=zztQ1nl@^IhN{fZg-P zM9zF$g8(3PMLX<u)jzXh>v#RjpGiB7w)@J;<k1ds_;(YY8xiOTr75kYJwi51)~%tv zo*WA0JPGY$C9tqR!AG}i%%^a>>?HG4Y2=)hm{ThWXkPu7Tsx_^LSLN`N-5cVY+d}y zQ<r2zrf<Qq)0B8;42OXAh}wPKl2#cw_24K8=&Gd{KA$vViualHO?vwM_c!mC83Q8P zmk(eizBGgJs0sQf_)7pRJ8cJ@>a%tP3%LghKC$Ld@;D}H_C6D~V`Og1?yA&(A(})m zhubs(d#4b<X$+<g7+aL0+$$=(Dc?xk7mQt+tlQ+hp5ZP^q#|yWP1cUN(&o2MPT5jB z=mFmPYmm{BX7N9T0iFgV5$}-sklrg0r0g;NSA6h)qbTiP@$%h|>~%gJ6G7deAihll zxr_^TUkaG0Z-m_>_lRFWorA%1Quh|F&=qVe8BxKyecTW`XEc~mx4hj~<5O1Ux%O&# zicCl$q;{cf;oKb|HHo7dA&%L!_@>br`=j(r&M&9T+;1RFhMV5b#7c;=7?Tk*Yu3F6 zD2nhnada9(jcTT0@f^Xug94gB8zI%ZrCi@3+L34?swFtuC;EGIWX;ZiwnHFv0g7~N zhwg`ZVB)6*{r)B~!%6{PIKt=hAUC;+s?fCN=~v7TOFszylq9o?>MqYaN=U#*tc!b7 zXba~KOLy+aWzlKPWbGNfE6HySZK5Ct`NZS{F=DFXyK7{vO5-F<_s`<WBnUbC{|H5> z1eWKd=7#`ae?0&iX9M?|$kPnC{|H!H^t(+pXzLg{(5T~TUy^L4Oa%@U`HtgqZ>THe zDd9{IoNzY!JS}DJ)mq?~g6i}6CGSe(K(ufz4+1HJLi*!l`rV8&MZkAJJ_&XcAgzCj zQCjvp6K7O%tm}Z!n}pQbTA#U<<VlCLH|XTw*87X^pML4h4Tp<8#xY{jwRSq2DB<e_ zRj}y@QvbTOq`IMfkDFHRyz5j|W<#V@>KE^NDru5VG50BlJg#g`;Jhw^CZAw2Y6Dfa zvBm$GnD4CmecqK<cKjX*$7kQ*n=+XbSM_8ctge~p&nq7EG|IkBBs5x>iC^Gwg)>%~ zKB!4J8#}9n9K9;?>a6hTG_?^Q?T7jJNj-(kg{g8IL5oKQRYlpsK(i5zyFs~RbiRY) zCuR8wsfli&RWex#0gGdf-<nkK183+Yyn>1m(<<8$^^bdWML_b=$N#Y#@!k)iqFc^7 z9bf$JS|tx3*~nDT9{LXnjdykkei5juWAh}cW+<j#mgma3-^D5=<)XI1Vr({Mt33eM ziNQmqlpW+P%}J}-8!!Mm$AsoUTqp4poTUbZ5qLu1E{<R3b~fg%6$o0f3OEC(Hm>nH z8gy;dMc3Z_@!HZ$*$k$Hj=GitAlCAzeP^sADq%XbVuTAPzV54g&A0h8&x4CWBp6Fp zrt0U1R$qS!%IhgV_3bhNcszAaGTsD6ifaHmJA5N|7Qe|2(f(I3AZn3%!+8;ibY=Q) zMTT`;uk9x6wO6dQX4AFYsv`qb_fkV+9^2hw&0cUa*k&1n5@V|4L6CiFGu#pN!14q` z$|7q$HxRY1y3!g_JOB?5Od26~n<WAg_c63mj*rFZ6gIImjbL3{zbFlB-y_Lsifn)^ zg)`B&y=9)IA}<5pyBX+oR<&QW#`G4+GYjHgY;heePHAGS+y9BA7)4F>C>@U7=IOzK z&YwBS)k$=n2cglHKgVLp-x{0?kqKaLvOQKWz$U#Sg0Bi;Z3#vzk<*S^G`{dOWVqXp zys?hg55Ynz%NsEgCOjjq8@HCkr-um*bYs+ZWTgQ5@#=+m*Cn@jzTKA+W#uf?I-%O& zuj05si5B?}ER+)i4sT1T>C)CM&=Pl3paI$3^%Xpzb55`AFtoh}s-oj3FzUcS;EeuK z2n@!EMareGNO3R?H)sI9ullm*L1H~lY2629(>QL`jCY2{sErW`E`qPw^BQ14Rh}nX z)s$SH%y`I;kYSR5y*noWO1x6$Es`k)H5XFh|FULKEor*~wOX7N4q0O`M^aZ~z@auT zgmd5kS3%bTGA;Cm(h*0BbS1Q?eC)8J1-A0J_ffC|(R$6Zd~sKU&srR+6Qp5(<T91l zYS@gC>DUWra2e)7jwYziqUXV=Ynylg%E!&q^lY6B*KGPcB#B7Er&_?>)Bto%{zfGe zh}49c4C3}1(r4*yma|?W@s0aT8E9frz_;0_d4jG9@s#OjFVp#(VF`I={D~-MDZOe6 z&|Ui^Z?7XhI^orjqS`WQXT&U5NDDjUsqA*?b|8L)wsFqoj=sr;ejdETB~XS$VGRTX z0O9fWoO(=iR}e~1C~+{jQ@kmD$U)qBT@3py<`(ATlLU8{oSWrP3-<_-(7}|+ePVGH ziH|WaU#>Oz<iJT;r`oY^DSL#8A76@|k^k~e9j2#B6qqFm?hyR4Q^hE6K;a>PGjfmf zpw7PBmBHa4xNjJKnl5hfy>4-D!lP)_V0X`EZ%>&ejm}enE_9LS|CHa)%6f%;X!*>B z4Hv2s_<g7DG!SIqTvm1o!7s6}y8e#QEOwt+`b>)tTVxehJjF*O&N3}}QOesc<OKK) z_oJAGeMY{$fNfC7-GF0$A}}Eb&QO;H63Ko=&Fab5iorAh07a8oql}l;7_QDeL8@0G z*RzV=>y7g!3SP$!FW39P!G=J*LhMrx#8LAItFYiwTLowVY8Eb$nkIP<&u*%Opi0Mc zREpz+zLxF|bCgcB!Rao0yXLoSmM$n;*07=>F9^xlLi|L&L-`bwyRciA{7VfgyYAfK zPQkEKsYd;D1Cn;(3(LnzT_L1y*EGxzZZ^YNWcV}|e&tg7ogp;yd*pI<sAu9LIbFVf zovQ(8)se-y5xa)INQwNLv336ozsz9q;gi6A-km%1RAg@|ENe-d7p(e<f<p1#mQwb% zCFFMD3Y4bGIKGAf>$aZo2|chwVx*uTIA1-Xz|*;a8F68jdtye*Z`0#~qw#2cKG<l0 zW>M-8G(~BTpql%o(Cypc{W4h&Y@n16;6Un)DL1dZvSl~qQnKRIPxNh_3MUs-C5&wv z_vP;C#j9PYyc-7@-2kCW@_PI514O<Hg~9BuPw(BnXy&fv`dNPe`S{vlf`wH0+kb@| z9(clHsZ~M`YyVDl5vXLu$B73h%q=BA4D1qsL3*9{0VeGkMTYFZT*Si)9}h(+f+j~q zt9n2el5O%&<f=jJ#6<Vu!6CdiG!yp!Y7@ZN%(48$75Z%mw5xy>z;-Es)=ebNKrN#e z^1RB7NFu0rj934-6C!u`6T;i*dj<CPz*n507Z#bx7=kWQ{0^r*Sndm{s%$vGwn03T zxZ<4otpD<&`d2Hwh*XA&*AUoo<Y@%X;n7bThtj50%-c+Q!lXae><KDGAcM3Jn(6bQ zW}SFp<q<E1JG)P2ly9P$L88Ev!5&pc@|a4b0&Csca6JD8j`T;;F2n}35_w>Z5)059 z;B*1bIc3Hp-fG)-kDxy*^-;8Nmv+?&IR$TpL7rl53Dmmf_u?Vz{=>rBk!6L2<qBW1 zn3h?sYP>y78GL?DNog6oZ-(y%&mY)!XP!O6<AZ2^$0Im$68?FBJ}^{!@&HJlE>v$C zBE2n;qAe8M?&(6tPMip&xncZ|#Iikd6`~}FI&OVXjd&z=2AuMBnkE8WpBmlxPQ8bJ zR@$YY4R<}*0nDrRZyKuS?ZOI+ylcci;NsG|kj|a=nhQ-HAwPh7{FDsHJ<{I9WrHhf zAz(QWc-?f^HEzKYZZxU*E{fqEm0;f_W6#d-2majpTYvYd@XS8{mnn_JIktl|>L%au z?M##=WJ$b$<A-R@F_Ur29(uEJ9Cn{z;lZS_ql4!@=qj@^pQBp_{ZMGV?z%Fq2y|xi za~r;}0mL_{ivU~>NK+SYp8p~jo4-fD`uS&MPyN+13ni$q=VLVDysjCC;I&G**9vu| zuR8@C!fN+Rl!%71<iavaUqF`HeE3D7zQchY^qE#Kg2m`_)CwOaNtTqs#2s(dpPuTm zw6+d?T^b#Qy5$bVZnrje)e9AqfA}sA1g4_1{31`EdP(@2i8|Kl{P(Y1gp>He8t+Y` z!nz;-fd#1NMu|_ti{QDx`TfA+kp(PM<!|?Qh3DoZ3vLHU7=1!5;R+Auh21W6*1X5O ztnUrRczs;k7sF2j8mJw~I9*x^-xat)PRjVDWu=PIR!YYKk!eSqAN!wt?uNg$4806T z)+LMI`UXI*tw|`@{;&_>eP@rUHpO|O0--$y^9y0gYcWYYvZ2~Et$#MHIs0||**qZe zfb1N-mUiU=eHC<oIoM&y%Kr5pb!)cEu0c~n&uMPFnx6C*z0WYhA?R%J<^(HD&9uv! zTqa!r))bx^js8j|%9if;r^&%dZu2EdIQ1(T!3KSyFIOx?Jnfa7y2rutJlSPGe_tYG zk8miSxCkZ3?1gGl7jPW$cfeCs<OiD@Q)zIt`nEJrVik0M3=W0ztJVe0oF|8|lrm%) zk<wNJhj3Mk(&uh<TWN=ZanW(9B4jCm{FCVMu3t{w!HU5uYj+r#+%$RYLWo}ib4AK; zfG}`Qg|vQh@$wHc0`ux>fW&HzqXI!Abz9r|DndO0C*ShR8;>Do$jNjqBev~*?Hajk z7*=13F(!6i^l8<nDOJ=+7gmWC+h#lOtZJ%D*HS6}faSH}CHFN8$Fu^G_lI0Y^S5>v zUM|vIe*54L=0?h^2;y(L7iEj#%-Hq}$ki5LM548cY=DguhWEq6!zUdLfP3Ic2(xRr zkUQqrHFv0rYM5|q8W_Q4#2*Wv@jx;tjy;msws=l}v>+M%4N%ET{b)$5^`*hIqa}l< z73KL*0V-CB2LOE(bdGj3(>cK$XxP9twu1*Df_1^id;tG)ZB-K#Zep&!L}<3OmggzA zAH0=MhB}H?z-S484;UlZ>lg9tT^uU$fVc%3DEPelb_#pb^O<sWYQlb`MbymM5Uni% zI|gHx;~d&J;Yn+4!+O2n09$7ff;-?HhhZ~Tq!@>rjOev_*e!f6C6d@G6eT4p$n$n9 zW+y%i!+pVm0{cZ`70qYp6^s7e18Cr7qWMiY?AUj<92W-ejUFEjytEkjk5JH#>QMfB zfW8*2%8yWz#c%uFg2kuZl}EtLOF1ib294$noo^|>P{P8=QB1mKrjNR%3I+^J$9&!M z8Oo)1AKwTq!v&*pw5fnns1hORFm8_!e^$Dg7;W8q1SvUg0q5^(3+Ddb1DPw7F|625 zGI+7ED_+;a4I(t01{p!ltSZJ_Y4dyZeT$?9DcAmJSDUJ|GKYg!tmFFa=jDBc%^r%y z2$SA0SI%{ZIa+m=9hhE;4uY8G=FwAVwwJ1gVuI2aS)oI1LLZFi)2nmtSMzC^^F|5I z)@QqcjnCtU#}?1ZcpAPLj3C-1V4|@F2MIEV9dJcGNV5pK{q88}A!IU=fz#S=O3sI6 zQGPW|=WM^REUV}u^__Y7e&_9HSjbkh1koLv-OF9Yqe2dqn9~ieXGebgW2G}!>|-~| zA?UsM8gFwA3LG-)x8s?PSth}ymHmUY=5juOktw&$xp+Um@RmUcE&6xpkz^O429mI$ z3b$}u-PHF$&5B@HZhfmEqAqs|f!>MQV2*idw}a)LFT*kmLWNg(E=Oiph{O!#>3YLn z+U&Uf0e5*B4IW<HaA(07n2;3hxoU>R;dhIB#+=?8J_f`~lSLDD^RwM5U)B5`cx^X% z(-e&`b^T;VQ~+eAvY$W%Lz`Qx#$>iPdIFR0aZMN-rx_RsmkvgXRP6p4=E@lga~YSN zaWEEaolXxM?lCKOuAuzlg*2aTER^?MQHUy!BY?u0R=!7+aWlOe48KMas<|VJ;Z2-b zZku2Fbg!AWZ&uPr4k>iz6l)S6oAx(1YYe>$*hzdMpUk*jzqJw}@U=k&3u4*{E2Tgf zmERh@DA7iGEpjNn5PtoX<{Iq3ziX1D>ltypO497<viW{YgJCn^)J2-BbKS|9AQlrC zKji$n*E;X<u5WFIO`UyaEb~GaW<zGW0~FAI)`V3z^;ct1EqDmTH>XxH3?I@}o6U3Y z7;9r4AB2?!`y@`q$zi8Cp0!dHR(JgUp5orJp2T}#y3&h*(KDP;E-rc(7b;iIxYg~d zz%r7Dm{Fv-dgUb%*Y12NNfSNucnCqX3+a28L$KX&K!qcrSKt7&jAtB~nE*v$G7&oz z-p8S=W=_g7_!DN8Bss%_;ipvThP*CP5>?ep72oX{&Hgk0T|bN!6{%`U?+!#-eIR<w zEKW5G87iGD3y%yR$9oilaWFt5+%Gx5ksV89X*^yj2MP;TaTH=Eu$pU#El8*8$z(wQ zp39LeF_T4T&SV8~t<Sk%A4Bzp3~*Qnx@n&l3aSq9<FId!_Gpj}d`wGUy<O8PTga$8 zRUstpD2vkV<n1C1flt+^LV&eARi>`Cq6QC=rNztJo4CfR89xkuU*O`rib22#9FU<7 zO|0C&JW0>H+3qcRs^RoDHKA*zSw>d;kvE(cDM02}Eb_~yy3yKXtBDe?I5jEAkTB@s z@@;At`>Tg*gVswphq2!0aWs3SQk}LIIBe5ZiUG+3fDV&`0>6Sm9AZ-O(3%RCu!v5| z4ECAr6uL=fUsyL=4V4gqtHsQ*%@qiL#!qf!qw9r2XgSe9jRh_D-6fq>yFdx<9>SHl zaGvAtx8U>&%a|<S>}{wG?bMa&D^!!jEg3(&S1+@@Wb`1H9X1*#l0coZLm&kRnqP+B z|DrLbd8GE>%He7<Ec<^D(%)E77<VLx0?I1R^k7mm3*6)Blz~={R{h94Cq=GM848YH zl~@s{_ZAkM9Txl7JM=Pk7@6BmRPK!^{NZTsA{{hUKW<+K52;#au2BB_u-@W0W0*6U zH@|DdliZV(#TNrwRwv|VUh+MXQg&hhrrpG4&QG$0Z5d*BjHi4>7r^@nbbQe~Ly1=9 zD3nnYB+c!ZJuYn5A2ODs>L_8ws~V+zPa);t(3^;e--<OQ1P@fIul}!HtgG^O<!$0I z{kyrt7c<-|BaAImvd)XBEcG?^CkuDpo8BCn<~@lmxhAzmfjuxf5F-#klzq1uuT0Wa zs^9d-q^ZE~9*=5ChIov@YI@LgaSXsg{-@poiKuRnlApm$Bmpy}Q5&mkQP|vvF2I!m zl0R<sVKPFix*0I2<ugpSJ|u(mEbm98PZqRQOuGnDsMwOnJ73dPmfIM{`^FuE@6VxS z31M_mm#^B4O^zCm-GB_*Y2uR&L}(L)S!?;3pK<x%|0?K4PB}CZCX%zEl4)%}kmd4C z6;Xeq2ZkpFO|Qq<2udayz8F%<wJT<yw_A}Rmt>5y@=JLO8lXgQe9&C+9@dk7c=A!e zBQ4j#D}J$b8zcc;K!~T>Fl+H7Ec{cyb({y<4KgHVY92IkW2ixH$+5MI7=j=P{8~Ys zCC)Wd!q|qQAqChoT)vG*Zoxh`O5--TduHRXdGyMVHJu3IBTv<tV913Z^&&Gh57anl zKeDWrK33L~cFNZblNDK5m$A;bFW~)-9l~bupfdS`2SGJ(PX^X_9B*ASR)&><rsFbL zFZqhzJYR?Hk}V`4Ino(<Q01CVYX%-(CeP~12=_-R99D;_&-StRY5Qal9ap2wb8uG5 zLchVkraiZYGI5Hse-2|AH!vNZ``q~!c&7(YzvWrZIz@~-3Gm((FN9N1(SQ{+NxV$P z4kAzS2AARCvbVU6S|K(z&WFvJ&|Ey^TBP+WP|b!Jy45X~>StHxm&pC}&+bg1g862V zIio*#QT}6A(oU%gi+A=z`Y&0RX-K(k{mFb+SbCj)d6s=_l?Nv+9Yf#D3s3k%?|=oe zTA82JS!5ix7SaW^R#}s|AB~V$8Qv@2#KQ-G(OFsLD>OrJ_=J1r9994L1aITV2E^;d ztRb#xr{w2AE5JHw542LLjIMlX2L~6**Q^n4&OlkyOi{;lPLap-?5XxqCNe#=(ZVvJ zs~EXB*WKD-7fnvrTcNfYR_d{>tqzz`kOlVgVjB-*-QwgtZsN8%yUYYgsDWw))N0ZZ z!2gMyEjn49x(~-mGJW^Z1@J9R5T4c){+NmpX@+?$*lS<{Krw_j9{%v@HL@$WZ&e@8 z;(#5!>z-&aVb+|7(&p#Q46OIh0>jHyy=`V=X+dqhcE^1pUZgZnWHcWOo;JOsy1q}= zVbBXor1P$N4jwQ7sG-lX9Q}TCD>}*E$iG^#K2lxL$Megr`|Mg{1!(d|KKg>(arSo4 z!?d><BINHlq%t0CaZx^x{7@yhI1R*8Rdc}))=*CvF0lH6Ig@4k6t3g0wP@Dr94t49 zAZr|SRAWp$1(Yf%`_mb-`?455_``AoULcW(6}Y4)!oi;Em~C=aj_(S7DF#~12tNCF z%@iC_VOrGR&d+p#%0#gcI<fDClz>i5jLxgJIy6HHpMz0cwcmUs1!5<#?7P-1p`P{= zVjz9!Ny-DESZ9q%BZ-63&y(=XI@5l`5Axb2D@NGYIl@6vts<sDO!q-EC#H@rlnlG3 zgG9E_*Zu>Tm40G~@D?--fw)Vo^+EX!rV8}S4&$AlZZ-n*l8R<9nJE|q0!@^Up11cg z^^P@*^LSnp)5}Z6_vM;!{yy)P)E3?8ZTb-q=MII3op$A{xkO0z5$bBV3f8~pP)<Ic z+eLD(eZ1g1(Y9!T1%Z4o6w*6OsLne2C~FV$@9Z?8FWQdQdR`LIyXi`I>3p%fnFW?H z&UNpZDg>_iLN{8X;DKJ)C$K+}g$>+#IRa=kUW*U2@}JyQWZQyi=L}QxPFfx=_Z7f| zh+cS8x4*CYDLn$UriOThx!hH>Q-Hfg+88Y{jT{$}B|WhcD&mMeLo>D_3Kj;8tscOb z5<KD(Ugqg<qnw-KF-r8Kmpcs%VE+2o=!(qx)t$FULN`GMfSu*;-}SGpQHrT@`0T33 zOG0{J0Z*rbwElb+<s(e+blvWps}&RSprfb+;T-^-Orlk}Ez`8JY?Tq|7dFnYm?TY$ ziWt^Nh_P=lat9)~o!T?rS3D3mCXAW@qiJ-9I(3;*7F{N{<M5r>;3(f6+Oc}7Ezd<^ zQnN$*^x0cz+bTn)(!Kw2?ql5phzsAa0A>}z4r+GOU97UXR}z?c5j>e3raX`!$2;^A zGZZ`o72d1tx0P8Y^qHPk-|Z}kCY-B;V-%2lIJ={J5XL7q2@)Ez<6iUk0s`4VP_q1y zwnM?uxQbXt)Y1b@Ad-u>VgK_Pt4Q_@k|613pF@n1A7=#6m3331-(0Jn8w>@0%;PVg z`$WnCNvbkY*IlbLRM%CLMEbga;K7RKrm;Z&yb&+m!M!0AUW;hCbKC9a=W`>%>uk%` z34CDgi2#se#_OXT0~RxY$5tgLj?cqMd|RM|A6{Kkd;*Eo*ij_AHsR3+wq$;}Se>bq z89GfHW3KpHC#O!{q&`<J-!Uds+6N%Rag~y`ISC-xhDMYxHU}?fG(*Fq1WMN~XzRvy zdfDV^qmPO-x(DNj#ypIMoVTsEy$R10ja2WPwpz1Sy3zqPuOH?3T3VyQ4X||)5Lxl# z@z_zUY{;chNux^tBDiJADN}^EaIpP!_3LG=wd_7|F+?Qu+jbtdR2LnOkf{!Y2?vXc zdMZS$aKDFPtrYKeiuLcA-Q{|puPM_;*Zw<A-<Gjob51f8%Rl*=O>e?~TW|x{ObDD= z6SPT3%~ea~Uw1GZ%C%@Lh!?i+vX<cC-|j~_^km52?R`0Cm^s8F$s8H~pwNX9RUCvi z)H)6`Gm1N0xzBCw?iUO3bde((bco|$Emm)cqA;+5P9%d@(S-S#<)-fU(EQI!>#qR~ zVLImo{D=UKb<zfL(fIn)o5gaRXCf-!zOOWkuy;KIHP@We8M?Aq0DsHUo=8p{_n0eJ zY9JElu+vshmBGn-BY*K*OLHtqe&$S%-z!+#Nirzs^zI`yaxcs40REQl&W@DCW5`7x zSF1b;47J)lWOMq$$g1CWY1odkzoK-4RL~h-oCk<Lv-7*URexCo>0&IOdtu5UtCVGg zgl*;y%+blGpcU0`A;6E?$)2kg|DmJb@Zod*H#nyBMU0FOtni>811KdgSZ}_V=Rka$ zS+9dZ;hj3Zh*}`MzKPg-5uH_eTxE(Hq58=i_@S50lPm_eJT^o!n0*JMDAee@6eyP* zA&L`s3EoK~_GKaH2+038xx~vQOhgy_3vec^6K#?)%QxU%W>2<Zk6moN{AV_URQC3J zD3?iJCX;C`fU%^I3NPP-Xgd6HmWPXJJfb8^%ztM}3)*Ql21c+=S9+~%f*oRulC%#o z5V^#IFvq8F&=TR%<wCCCBP!C@_w^lN5#B*k5no$saP*<;gdQI8-%yQ@3ubiqWS_${ z9O*^C>?}~pW%f{djeD{Q6Bk0(IV;`S{W9orK`q~I4P<d`jBze)e|^t4U?Wi5Er{Q7 zT-97jlJ>vM4LkAu`MAL>j@ovo8@UccUk&z-?F&6XEI1$8?v*c^*7HCU(~_j(3kMa( z#ajs|80dgpw9>IlI3W#6UpJ+@s$cSlG@4oJj18N=r@?jQDp9BG{aLH*T&ObZ!`jbE zE5V#Z?z7l5v>PVqOmp_W`n!L?F=o;^E~VE9#E-C-T7S^7z1C!%%Z3jZV{lLr4S?)} z`b<W-<=%`Y_@wqazdSOA6pRC-rSd&9Y6<LRfV@rxH&H=G?5Rv?cpRO^NXyePZ&%@% zeugz&l|8<_t5;wM;Y_N8WFnCw+umLmLp_2_t+!aFM6f8(?fJ?g;e?I%iaY6owA;?6 z$OX~ZoPe1p<v9j5GcCkcMu_MTTdne1RCr!3Euf<*mnL?edFxmJze|tpD}V4(aa9Ng zBi&CN@h+-+NBY{~I=m~O+>M^;r1oyX+Q7)8j^Mm?#sNSoS~`5su2Nq4L6^MpJzoIr z$907uq@bgPM6A}k*c=owK@3%R5ty_HV;FKIKBB-W!Ru)t-)GYOh|JRSbH_VDeI(iP z(Bd2m&0{U|j{8~vhMMcf9FVZ;G<Xn~zO<qpr+dB-lS#FHy9d_PrNtuJyiEtAEPR_t zg2?n)?~AyZK_+VUsEf;v#d9QrWEERse&|AG0rrzVdi|!~D-IrK3KpVg^zQjG${k8x z0>)+Jg*rvTS9u_(obpUGzqP;AicRmTNS}T+6n8mO*G?7~!E>TI9rHngf?PF<A3iP@ zSAAiyD-+Ge;3eDK^p2eX`4fQ3wTm+i3UN>TW9s#zC$7RZ!O9tP3uWTc2VxB=PycHy z6rl(k?`FFY8e_Z+UybWF2clnltmi6Vag%H6<BbE#40;D-GPX|9hpd5<J2pv8dHt)H zliw)fmCz|sgfo4E9~~vQMA>RP00*LL-3goB+tD2WB%<C&c;@fAIKamG#ytrzQ`+kQ zh|?*+FT6a#{^Nq70@NLL&FvAtZNzO)k%U+2ZnXNIHa>{w8hE0<b%tc3&x|?7g!Awj z|JF|PrUC}}{{SsO(!YFMYZhkO=|!}*LTF0eb(z4E;n@lym{wqT0uek*fpU>1d3sk1 z+_M_mirT*7pGN4aRwt0_><aJ0s1JqPYn>>CdXncoLa3iT>}$*M+M9YjsC_Cb&(7<c zA`#nYn!sOPM?YINieBig9pLSK8C!tY`%!jm{#S7#HHvQyc8VZDYiz|Wgta~e@ez7q z=##CNGaPV#X8@zc@e>OOHFf;>2H_hA&8i=IHYUo%qM^o^Cip@6K$rdFZ25uclsR(K z`%+xt@iq4*RYOg!42qJY?K`ko2;CR$2e%0^>|)BxbQ?~(MUlbABWdJ?0gS;g52HmU z^b4K=M`OP`0qZaW6HQX{mlafk9MiO)!#`Hq_?k#0_{>mBdWl^T)j*robHL3Ps5L_& zO~93wd7I;W{;=o!qy~uuVG%;MIF^kp#h1djYE)dms9SuXmx|L)zP7sx_S&C$@G4JN zcIbU7g;0Np>0bWeV$NdFk#U`LN7~CarrwcC&E7J89J_Q0iavaCE@^7O8Jg}mth@#) z|C^8OE1afT^Fx}$E39*^5V0brzBfbyBemKN(sP*=rV+2z%%Ch%KcqG1DWCnt1+gs2 z0cH(7FPlcwS*g&E8@ZXt#*#KM<Xo0Bvv`?qee!YzhEI7O00tQ&{d0OOn!eXE)-)(w z=WT=_;^M%Q&nkvEo7lCWQnpN9KB!5wVH<nZi$<A{EjGO))fBGa=!k<9j__-J0wi;C zEDIqzZf(YamN^F34yZ#T`rS2896~#7!q^tX)?5}Fgug;@RCyR-JX|jt!hdIP;UzKO z7^7}iXVu4UhhuwwGspxX^F*)ZVa?)rVnI3geE!BTi`fiD23B(2wNM(K5z@|xm2;Xf z4A4yw^tl6XqoqIVsX)*oiC{7XL~u89)R*SwNz&<@Sag#`VuI^d&0F=B<J**#VT~+E zF4R3HvUIzFh2Ue4acpSzIWO_k9i3t^$d;+_FNIuO?S^t)me?}PNSOJPWp!Sq+M>-1 z(j<oOtBRRd^wZ}6CEc{r`1aRP5H(STu*T#B4Vy8!oG=azw}o}Pgxgf#5Cz`Y<%-B_ z$pb95zSC9j6%8&vmgY-?=y#lp-8Bfl(czB<*+_uhU#ud|C2%l~SiPK4pup4JPg**> zu*QtoAaa-ClwAVBcU<{epH2=PgiyCV3|e9w?z!5B+gJ$Z=#kpO9%O4l@h`=?4o&bm z&H_0RV>`k?Mpwpy{lw!>Gy@1N=+l{bn2&aqUUBQ)kf*}U53HjAtz_n5N18aA72$A* zniMs_5l4!?BV%b)h7CGe^m2k9;64L-B22Yl(i?9fK*5rVAD>7|xF+WO@Wedbg4A3q zx26j`qj94=o8Rjuw+SAaD4Y{RR$WyCH8f7F7Cx^JtLglq0-#Qq2Vz9Feg9lskRGxN zDWGB43aqQc_Yd)*$fV~BKwj8#gVWYzVk+(GQVQf7ufpD$xb@8*yPGS{h`%6Y>REro z7?~V7gA(3zz@wp%Fj;#7e}Vr|AV8l{Hs-Vd#5Dd(BIo?Y?{hE_9l@?vTLfm#SV?CQ z^H>e@hC`FRCr4}kF0=D<pkdeVSK}x(=+6z<j>dFFkMUT5gEFBa$vM)!sYnpyv_e=y zz(4Ym4yM1R=J;^kO>Ew5=WYy^(~<p)&lxY8SrXjm{{_e~S-Z%MKD#(dO|IeegvK1$ zCtlB)wf!+?>R0oC4$4=gh6e{sY1DN-00r!RSFEukf3(j?hs;_Y>F~G&W`&IDk55QP z6tZl)eZ6wQdL<g*o58WL$}7U>s6($$h=Y5)Ln9<Ov~S1n)<yydW!-0CnhHxU>|s{N zU}=bT9{X^|%@Jculiabwf(-oYa*B-$7slKZwAclNH{?2{PgcChM~?c8o>ngt#Th;Y z$Lf<xZ)lUr+sM77437G;Z$6vEkS$0?xZ5dKDVvi<$4O?oNyrEl6lh+4&z?40B*YSL zI>Y=$&Phn%u`L|{LS3!D+XH2))>n~2+9!%P5cE+Iiw8Moy&yA8Za3bR(j01Gh!7`h z3NlAKRpb|5ik;I01l`6Riq=-=a7B0g2CIS$InDSqnv4!pkw6uB&S1!M@quCfKaC|0 z_v(FnX8vVrIlzJ$W6^6I!g@bOG<{O(xCX*|bdgZ!K3{TyUv848Tz|Xua?l+rUe4Ef zRd(p8)g^{yQAK>1GOA;CWbADpJYW<TyUz}E)o$YlE6c|`=)zWoa)Mql@zRp7E@-r! zQz#I;{HS?PvN1!|i;>v{Nu@lIVY82#+b6pJ1c<DA15c44EKSWRP37<<!S|@Nh|kbA zrhhm!Z7^Oe{5OgW(-#G9M!7j-(e?}dSc#bV%^xm9*+XFK>9L2Inu??mz0bVL(}hg& zv6aRiB9tVicT5Ara#Tu_Yf9H)&WZvLN>EQQ0kj<%+@PHnds=goU%Af^%Fh!^U^<g_ zfiJV5s79NY?GLK{Sbz`<%$aLO2ofmMZ><*tx%VuL`wp{p>D@*yQd6-dQvVm;2hIpU zoT7<J`$%?ADLQo<rh^xBxwcn3DX@pg<=+mS6>I-d9C|4&pkQs~SccBME+UMkSOFJ} zA;dOw9Trv;ja9c(&NidqBUq~AAN*6};Vd-02c*92Tzp}qd?hf4)?1trMjyG-<Nxm@ zZsR@VkV3Ory!>(lZw@ipJ)GQL1>q-v5C*L-+{luGJId}}Epk)H>bnPzxE5y>JmY*R z4?J|fIt*h<v;KI#OYuJ)ks4dp6#=uAaf^0~&H`E7T(8yzn-w0?=ud4#ZiieJ0TmGd z=QJ#@u#`q=_E$gdcLvepit^77TV;e$hO=B3c-DxP{2UlW5DqKYrf!B#7*LduXddsM z&3|rY)g+FHT}KS9^{;n{D8_w=Jmu<ELT(@lJnv#5sdkRX-8%@XgQ9RjPEY`no!oTZ zj(aDrCZ*jAv~t(dWK;U^4ifCN&@zI2Y{*zu+spV5*W&ngUJHb?Pe^18Ho}ytaZpue z-orut0k*DAJ}}M|6%ziB<!DAoNNWVyks9I|jceA+pGeXOq=}f#@l#d2cap$<1N8AZ zrI$!{l?+5k8w3Q&GDz-7;H6Kc5Tk(R)yP^!2ZKFBFr*e1V^7tY-80-{x6EN|gsqN% zRfOA#7g>?oF{;#ZSGJ{S!kbTrS|*Uz$@fT$3;yS<GORVVSz#S(=I^)_j+^4{5B=Nj z@$vUiqMmdO#GffMB06JEdF|{bj@@~3OnM>*V&!Jiw{NWY{1xR#NV(D$33fi3n!?3U z;Z<fh%&vd}hvC48vo3J~x$qD}(!9t;dW-N47SD^!yYGB|XbLEUQOm8>j}rZe!}Nhm z8M=ZAbako1>O5;2*XXb=fpqwC4VK$EVvJ5#H`$k|HIHWV0P@2al39>wzavwU$mCPF zK4d27)j?<8UtxuHLL*h=l5t|)j!Im^DBz)S-i3~=@Pf4)*hx;Z^Eb8lrr2)P{VTXH zj;_&d#qyt8&h|%*%sBUHC<h(nP#7{|1XS~u%5J~WoqLi#<d8Uva@5WhZ7^NDe~*<t zU91l^tzgf@1ZK-Q=+^b}kmKQ2x<1fWu<F4N{mWKT+g-=hT!2H`_%LIvD}WIt>{Lah zi6yL-B>m*(?iSG_P;}BYt%EtukQXWsl+tBQ;Of@N069V}sIYogg_;T>6L_Tg#$oj| zj1hs(Ddte%T(`&-_fHuJaBL`GzV$-u2f6@DdZe*4LD~Y0!P#cUOTXd)RP>!>l%hWt z^j62>3rmC7kMC)!@THRtgN(RFc%8=Oel-)sjY7@+T-^TKfsLFgPXmaXZZ+XT-0?TR z=1G5h-ov!@oY$+`^U+1g?5Dwig#|K9p)JPPu4##P4YkU>pVFJ*OB_()@&y91obp;< zIu94JYRPZvEX-k+NkRyqxvkmkrk>^5SB2K((U6)*5+Y*`N`BAwoN*AY_DFBy57w$y zedJ)su7@BQum7B-_FF^`uq`!(nvT2-+uprvw^pQsBA_L`1?E&jLd)txc2UhW#fYAn z!SUV7J{1p*aQY=jO;iLyJ&ce~hQ>HPa~rgwa-O2hHRh%&TjnH;+SJe#a2jGOH87~y z;d{&h#VXWbO?lrL3B^{j>Mn<a>mtg?eCl%YBy@hHzX>}kIaR*1DTQ2e#Cv-lmqY(# zo|*<_3O7G$gC|vIu94mg9xZ788Ny$kY#?nM6DxSqh;{hOnNNi0XOzUCCyb|Nfaq7u z#3H@U?<Hot1|z*i*rP3+Ui}(b(@n?grY^IivOnlBJ82EpHEN!OwneDYg7<mtG>I^9 za2tGTX1B#gnwIMr)diu~2ZY`uHw*UCeLdS4T@p1kuTV7$KKq&n-$%X2tUCdI6E$SG zZ>TJi|08-r_yp%sDgH@%)_xBZlAdnRT{e>>+b;%!l;77!)7LTpj9oG{S<A3*HQSIG zmLtq9=g)>J$iR^ptw6TL34@#7oNOOm1NxMITAqSG7J}j+NansoL(LF`hrk9eF)MFb zTMsC&XOObiYOHXqYU)7&-WS2U?+eq1Ws&(VsBHHSllW_diQ7>8oQY&;^9dMGt~6sP z&+F^BsLsS*$}9nZ`C+6}hz&X>q6~-FMg}VTz8Vjqb4I)~yAKO|xXu)VA$cp0uIm2| zC2p-auQZ$>&YQ@Gj2A{B#)Q+^^sq_K+iB2);w+PZw3S{g7W{Y^>kB8pB<gWlr(ky# zV8vgmKv`LVP9T>DHE4<n#G<k;AHso6`f?Zt$V}Sc?@<Q5_<eLN+hNk-l$;ZH6zC>m z{iTy(b9t=21?2w8lRIVZZZ8EgCKR)%>w3F``A#$9(c6+XXY0kc9`&BV3=Bv~b)Xz1 z?q(guo$}eLH^D91G->`E=S$8uy*l5+_V}*M-5>XI@5YR=5%~_K*S`Xx27ku8b;T4h zPB+qsUi%+NS01~cli6Is1rEjAuDfJh;`%S_gC@6SeITtk9)2<wV1i_yEfDfoynkBf zLGOd-C4c!l(%}3vR<&QyI^1`jY%@U^hoHz|)IKvrMqA%w(HA3un-VEV-wrR1cUx^K zU@6~jqTq~(8+cX8q;mJ<hWqFw23G4{cOJW(XD_?ywRRpwArlMX*taY*snsG4)~0$T zF`g<8!jvc@aDN@*;q8TtMzcW2(p(1~0Ae{0HUo7B;>9^90~MB=ns=H|5HfMmS%3YY z&uBC2aN}Yv0A~Qs*ZXLItN^PlC9Bj#+3j|(B2FF$ddraLW<Y15=_-(*&T{>&%sXYr zJBjhYQM6CSE@5XmZU%5Tgf?ei;Ay-h`GS>Hyp9}=RbfrrWXaD(ck6f49+p(QNb*+( zzK<*TCCI<}5O*^nWJ60&obi{IWKS;Lj52#n0F}&4ta6f96Yz2`F~Fp><}18uUzIOP zag}Z25?PIhV-|!hgKNx~BSlF8b7dgFm%C8-#Td5(z*ZSd;g)=U7&tEszsTd)zdVAq zyD(a+BPt7tC=rhGo&*;JK$+ky-)AvGG@P>ZjE3_8wB(nbzf6rJA%WSlza2&E@+3b& z&+I0V5qF?s_kd_#Ifg2aPRczgA~*VDC?AI2!Fk*J;Hu%!IrM<QNxF{^oG*Lnp<872 zT$Gm4$hU9#Q5H=~lK^LEe`HU-FWA*ydO=aU0%HMv4=piUBl|SErDw}?{StSRkw>L- z5Jl+lnBbexACvHfDQthcG^@t$*o&I2S5dg6*1Kr9PE1ia2Jcq0POG-SXz?m2vJ=nG zJ~l==5<)$3&niaMYRc~sk;WRr)_KJ#v@K^^;0K%vf+UXeg8tq02O{!8ogmXa{)!P# zGn$oYh~JWywg;3mIIQTj6VOUNCC1yat7<CAn^0p8e81fVY%)QLB=Lp9_c~q!&PF!d zJ(rVrIrL=>_HY;TD>XD}&ahic0K%)f9_Ib_$K2fMK9J9iX*{}v9c0Y};t0X8^}d)2 z-68#sTAOKiKW+fv!AmwG2gk;-5ouL&`$Q9&LsT-*Is3JoV&GnM&Lfr^x`kvg60CH{ z{g5W5KOFA=sI{Q|f(p*pRxCw6dr^0PJ)OHB%rwqY)3POH6T>pSH#aN;R3Fu<4T2)+ zU{YVKm5g|xEF@ve_M=j3OX`d-LFNRHbxNZeM4(BOM(tpTMZNlkDYjx2Zr6S-MVofo zQJ=d4+0a+cc%s~hX5<wcOldi`-{F}N{A#?j(OobXiSD=CGT+H`FuwsJll7rE6C-|z zR;cspas}<X%1|O+t|M$IB=bRZa(i1Y5YI(A-i<7bIrQWp7^mX^25eImVu~9uj!5Ml z#MZbm7F!pd63R5mmm!nOpYIBCFD~(T<AO#O-@-E+oC%ot!&632=ZvTufQj5uku~8n zPT$ZE4Q*`-SlN5Ze-~&^HVt|pwom_O{<@#Zx-^$$<xCM%h9+{FUH|Goly4C<7_wwM z;yT<Jy%f@du>^}pMDEBHfs8SX#p0q@v^A0v(f`m?|E0rXoC!j_x7f{cg(yF$Qg)S) zPJ+`Giic1^kr+dm+C!Rn0fpV5mBY?h)Caa&u=Y6Gt+r|U*T2uEQvllE!Ts}CQ~A|S zqq5mL0fN-rVWdqq#aF?-2;&}Ai}*H*YSL4rf^VAv-DmHzNR$wbJW}m+6VayaoKzc9 zK-BLfJp31Dh!u}dkXW4VxkG8hLy;nG=P<fQl%+T~1l;1J0;n~FettGWq5XM!=U?wY zzxTI3Cqa3$Sqqq^Bo)?X0C(ec>P*mHWBu7@a>pJvG@fd9h9r8;oBn87`_Px0lZ&HO zRX0>7;r&$MF6YFzxC-?AU(bDYim2Pbri{X~2(O4)M5s@MWo@6Q_na^`lU>&7-n`|{ z1<iVCjf?%B8Q1AzT5g5rAL7%#3RxcM(>_~Ko;^PEzrtX3Jjii0AFXpxBU2EE*p@o% zq{z(u*tq@SoL3oUXgP+RST_t0QI{jh0K1QYe=vP<F@Tg8y;dpgO_G^S$-a)I#3+QQ zQ*F|6SFEy>-DWNA98pdOZ1g5Z8C3q`x6#P*n)vDS1rxnVU89~=s#!r_UKc8`KAaDe z58<_9IT&sUX5yn38RgcmKHSn52a@YxNK1sbCqs5a7TKC~w>go3$WNuuRd*8L6s%EO z=}v6P-!3iPbGBZv9UGw8{|Iq);b-ec3U}SnEU_bcLg-laPD_(22dJAnKxDof^?&G% z>h}P)NQs_HXK&*mF{frtGb*PD`O&h&MVHB!*fxc`egzfe%CiR8*65HE&&FBX<+y@Q z#LV+ta*)+HFUhHX9#g>wR=dB$dGIP!M>gTizOkcGr}DnO-EsU8CFO-9LKTf#49 z>PTJ;ZA>RGu^-c1u_j2PA*pH_t)~cc?%`n~HKSeo`s7MZ{f5CiWG2Kye;#DgrBToV zWKxhMw{vy#oSKA9=*Wn7Ijja_Goqg4#OH%wS>0C+lQehO2n(hyl129ptx%2R65yZm zcq?yQD}4B4DX+9C+vUvj%eINIL2%hc`xh3Ki%JMx!_4G&NGK@^dDgwl`s1m~TB&rt za@6v8_OIfay=DAk6wFgqjK`m46)`GmQ81#C`@YA7M(V+;6WGj0A^x3i&W`<nVMrk! z1Gy05Jvl?Nbe79HDUfYnKZvO@ZJ}j!d7Aq1WczgLABF}z;gmQ3{;P1C@Bje*!W(0T z(rjsRB)=JjIfD&bIB?luP?IFlCpx$+=slfnM-L~~R8Ph{as#W0OY-M*e2AN`m#xZ* zzxMz__N`2vnQyKX+-M)l<{I}@OH-UiO*msN##GOaUGIO2mNEeck!<7Bs~p_cj?GEf zBdn&pzzd>tTh$YLkXxzMm%In)$KQHzcA&tC!ev0A@sN#VlcvBuK7b}PD;#=@XQR+M zdHmFGl))L3cjqC#iZb3re%l<p@H2yM`$^E~jP_t1jLVLeF>~?wo}tjolaWf!p{6^h z4&^I_uBz<gqE<Qd;}3{=gG(Fao+l-q&y0Wt2xfbxEAms<XxFng&P+BG$Ng^QtyLp+ z8$To2SqhnRg(N8m|H%d{zPwKOmqYW^q0cKLdG(x?h&GZp<KFHo(>e)nb|1Y!lD=z3 z7Jg<tedavR7*v?|$df?EyvbmgE*(;zDR0#^J-PKk{5AQw!K#c2M0LP4%T3W=*8s!6 zv^|`<hEp!kWt|6i-N2uH>Ev+<&6X*(Ya6<;TM%C1ZlM*>_dA98M$@maEwb;qid}yn z5qw&<e5y+-qWS7F)9Sn0!1rP6*Ii2<L247M$z%O3@@}Sy5Uj>t=jek1Cp9OoT-)6t z5p6Z@)vDTmwR?1#%AlMnZ-Fx_z@T}nwQrpGepVkn#{q9$KpiSF`c8o79LOTJkgk>V zgANuW&&+T|ZXgE;etOd#GF{mfG6}_-**v)|(*IV%JMkDMfMjnuSR)kpFB`?uI~6xg z#y?%$kjAh8Lqs9Vbke5chD0fRjm0qVeI2%nhY*ELK%Z+hgni%aEMOLd@`(~gHadDX zjh4?o;weRyCHfa*Goayv_X>7vLw!wvo}vmK1*g^!IlB?jI?v8IM_Z*UyD+i|r=^*) zODD)E@#AlqPQ3|?*K6yAJ?lR!9+s5N$e=HP*OI8QwscoM=2Zy}a|<==p15hCLwA=P zL$MQ-HQCl)oKF%o%LiN7hFhYn9i0f^dU=Njy}$W))lrGwpEIWAe(2I;j2}L?CQ{a~ z!7^si2ogI&45z{8Y=Htm4S*~&{A`!6E09(O`3yC#QKi6WN|Nd*L=f8H)hIIy|9l6n zMJ;&2*CL%TusUxZshDKoEnkX#C`oB8@@NdJ;wNx%SZb~)uTU6Iy)4;c8O*Hi*ICnb zk$Z#0mr4|L6fR$N(@Y${NzrYh{7#{YM>~O-3x$nxuMRNqq^!@7jmR`SOsC;FjkPyf z+lsIj3encjt+9t{ngYad^dhF$vM3Hbal$oj`D0NGKE7%CA`V*6Ht&HgUyC5H1~iI| z@L&J3HEDu?n7rijb!d$%J7c$|ChF3h1iIB0Tv3XC{|JaCP$!pY{5wG+vqc@8%6Lsn zGoOk1j7lGeDn18~NC-6?KE%xdTn9T{ZNO8CqKDNj5o7B_U~X}1Lu<y#yXCaFn)F<O z`>i*G>H&qld5I{2A0(_}@1`27H3gEzmt4?)Gg<{zVSSZmr&so}Ha_<|JINg{T(6Xc zaMgrVvwQz3s_}IrgS?%-EX97%ZxLe;UrpTcQ;2?Z4gwx)`-Jeo!<K@Q+ueZ~t2+L< zU@k`}Ukdx_yLKqpT*TeR6OM>UrSOl(x8i@_s6;ZRnzr_cyRXqe+Qc5w(|sc549;NT z<>ht%Zo-4uL&It32>F`qPIecV1@m+ZTvRVM^ULhQZ$P8~Z!m?{hpZKP2B^k5Tc`QJ z1dK|cF%LhpCi$>HRHzzVPwHDBTeWJVr2A|4=qJ{_|40$yTa=u#=t$`gR)>NLzxBwL zV=E)8{`gJ^46s_DIyawu2rVcJd0Od7ogqfWk>+SUX|?_y)}KnZ)i%?%rf_$@=#}4@ zEp8;x1lYilyj-bjiJc4tPgfN)ypXiv86W<LsF$h?0ny|Xz~9Czsc0S%K^SVvz=)~Z ztVJd9dRdR<obKU+=+D@+!|n5wT3+R7BpfJ?XQZz*+BpcB)CCz_&S^{ZwyKsib;kCe zL<<^4jOKl554{Gt@xb&0+j<DXW(r5{%VELC0n~XS;E9+yL`RUMO9u6CDa&n)Go)Pp z=c8V)?&z%nVwE{^khSxs*HY5I1=5#T17-fZ5)(!(f_SaoBJ&n0b{G6@!rtbbp&TPr z&?co=hJp?;WaU^|gNxEyX|t=F2T~2Ji-x`*8O`)7upI7D_r|Mm1Y~>g)A4A-Q^E*1 z0bgDGG8LvOPPKF_-zGYl?@Cvb@~Y=&6Iq}$V<L|Qw0IJIdmt>j0gKzm@c9zqnjCJ9 z8_=d!5tt<zms3HRIVA)<z%<(E0*@5cdHt|3-S=tq(9U>Pu2Vs=M~af3xcuG*8RZI2 zk?pftCCbWGCv+#I1%qB|(Z2*GQvJn-kxGv&n7Gm5(O+~wVG0o!>O`EV0v;mw9vO9h zQu*16)--_Z(1rQfag3fQ;Nin6dU2uLg$?PEjrb$X>}g6*a2SIgUhzH#N#xb9j<}hr zF`z}xGTi^HUny@2$Y#0mBJL@)s~X7>4Y~yxh%SB!wc+|~A&pIK^7_KP%bgyM;uHv& z`qpZ}RZS6T<s?uP)~82^#a6gyDPmH1g)#>*I7HD=eGs^_+`|npTKDw<Pa&QE9BBiS zXY6=M_p-2d<m**R`9e|k$K(HorF7RGux$c+rvY=H^briRRjoit$5AUpg@JuIs}3b2 zraE%0slUZP;3TNmMY`N$f8nSeJ`umPv=2zeAjnTu&#=AQu+HAt=c>r7aDDlhqiW85 z23UVn+vXr5Wa7UnS9aTpTnOSgVRh=wQW%KCwa$%OL}@#*`9rH^Q(242P%9$I7i+&z z4=AxDUG2@jf=sk5w&Q?CxWgi7ym1!*1xxK)Y8K0P!A+&vz06Xvlo$B5#zwq>vBHPy znuqNX>o>06TZE2VKZM>SSDTqz&#&~>Z;In0LMCK{)iXt|@@XUWs5jhW#pweJg#F8~ z!3#?RD_KLuyu*H1fch)URqlq7Av;1?<;)qjMX^zlfP!>4kUU31U6N~1nqmES@hJR( zYjwa+64zDUQsv*T4wQTuj@BKoQ;M6DrVZ&(I6bcG>1y9NTt8J=6>)Rl;xJ%$K1z#s zBC$|tFNq)4-#Vy#VWEE%DV=k41({}JP3fBk5eB}jb=QcF<-r2T)&>X$@pzFp2rQ^q zlVcYqpqLMP!_4kq_21h2*l-O>8cYLTO#kmZ%)2b|*1z5MN@AnVANi~&LRcyf(pF4O z&H`nFS*%v@$?qWt*F^qX4&j^OoG~60A~Up;_`o234~&xM9kgn*m`UWUSB1_NWJBj4 zY9RJ)Yck^LpisSchdDMNnHDKkdTf>|(8`gjIPJ*BfG=dtF~XtV?Vg+bi!Y(+s0Z}F zI)Ixs@$4)Q&YB%nhBZMKN1Yu6q3b`&6_MUpE7{Ei2AEt*-+#vJQ(Sa}pg}}*2@!No zZCkrY;a~T$t4gXuMqL5nE_DLo<ZPETviCGs@WpM9-==XB^gHVxCU(&A1G*uz5dW_6 zDo=SY0;05tNy<V~SIPZ;^@RycLpL1W(Ur<<3;}gGk%dwhtkyFi(k62>brRaKXwulG z4ITd$Oe;jIf~Xk@<kPb8h|LeE_7-?I2XXiICqX<{Q4&pXOA+n1U8*T1cy!Ie*acF* zXjnOgQ?H{w526{{Fs`+hSZdKOSIo~iJMdnSsxR*Ey?pTqrjX^A*dJkbf{l8=ChqV# zj>5#jrWR66nZ{o_-DW_2*3tiv^!%zneq8VbA5*x~(a~*|-5pm0>5lo?A6`ELk<5E2 zS)63tm;yi3FDr(|RC5FV-9&P<02}0Ozi`hCw{DT0yORjw+!@^xIq34}K+s=dO-H^{ z-tZAq{<u|rd%+~z!f66T>X@V9eA+GtNDl>FKu2tTm^_>sOskR+DnQ7i<qe1cO_%RU zLGlDVY8U#*brU}e)CM2rKX_ElcZlg8$Gqq|_(lG_tGhc<)E6mcMt#1qb>Z`{=mX6V zjz4PxnJlc3Jc8xEW~tL^1-ui(C@}c+fZ9parQL2;1m>3Z{@o`0yjS@xPla~}3sast zV7wJ`u80_Kyl8#i<*!w1q`NsfZc?=;psJ0zz5zl*njtV7y{tHI50_|T)!$!|oRr)# z2^Z#l()_tzlN{y$s)liJ2}?gZ3nU@dr2%p}81eb@%~Lt3)FGFwv!bGP*p@twCVsu? zC~U%T?A)uOpku=O19Am*d!eS{=gX+R`LJ}toX%&IrH2aRVte%SMt1iI8so+AVWPdv zvO|dTl}9cTF?%bCH^m!7h|GKP=ZwBcB{XpfAo{aQ=b^YI*@o`1`!|)Fxe2VL);1{I z8)vWJKuvk<xgb6m@>8$U$bp=+K{rIo`(kZ$q^NX_$&0&zXzX)H98IL=5Cb}IbG?2G zL7$tld^9Qxua#xn|Hzk3`dsd(6|9PDk`I_})cbByuId&ewKdxEF4Lj75M2tEu&?U{ z4aE8)gO_`d1aVp9&>pT)kWyS1H3dX}h9Sy?`pb|Q%Pm=l7;d_~P_U2mt_~$7I^pVY z;U2wm6Y<wj0<huf`0YkPq4^bVIKDRQsb>2je<LV0*_~2u4wV*Z*NRy^Gode#WUP>N zR-sks)R_-DhGwmVTYF9dK`=!av!U?)SPLHMo1=7^e8m$61>3Weyv5Bwgx?<SdB$a} z&rhQ9D8h~(i236FP90g6{J|v(Xuf~0`|=Od&qqK#Fi2Pf9~1b{b{D^MhTe1{Lko9K zmjZPD^EfDXTAvwuczK70S{ocAz97IWsY^T`=vv1ay1&l#)NnuLU|r2f=9fukQ{lA7 za@?=|P}%68TuZnM)7)RJJGapU_-WQgwCz5eo9YtMo9jtE+KdISCuAW}NH;T({<MkX zoj*N4H(PZt;37*L0?+cK+GAhRpbf5=rj#&u`nfQGHt@zo(Uu|t*k9%@1Gwqtnq#2T z2lHjiFjUz+U~-lymS89o`&zEQ06@lEv{c~=iu<r%!%Pa*I?CCYAnPpkO=SmdV^V$4 zvS}~eN6XGI)XH?*lQW9A&Aiq&iC08iD@3G8-k_GLx~z?nxJWgg_&BQ#33aX9DBU%* z)X<mvdRI!I9w;(A1F^zDnSLF4JH{3C0hBxVRs_Gt3rxhjT5If7YZGNh3`7++aZc=A zX%vIwNPu9K4W{}qry40*D$LF+aEbvAHUBfRQ@mi%+5~D<Io!PAl<^xMl&FLI6G`=P zbs!U?@q|z~k1|hk9oS}{D#F`eQPtj)HD>Edlp!8t4dn*&2+BnTw&hOi)<p^v&mIz1 zHV@z$wiifC)!I3PLJ!K+=JG0rZu<A4n_5G4qR%WAT9uvf?i9Mojpr)I`mgQc>Jxt$ znqOq*x@pA%jBgyq_(3wSa^4v1v?vmS2+J%rW-O{Qh2?j&Y+X#QA|WcY`5Gns*&IL3 zefs2P`<2N&+56SBN}N444pWXBkF>enN^~KB2-swiuY}kjODtY|ZKdxcFi>V)E(MnW z)S>cT^X|>ib11v*tIC?4F3GVU4#xfr>$JzZl5yT0FA3n;QB0?#j?Xyt6jo^ahrKB- z!)|lO>J8_y^QwgBdmtG+yn3J!FEdWFrIX4>%v=EZTs(S`PUwn}ul#~%#>nC~PC8x+ zTlQ%6=v_1O%BkeTe6Uze#9#ZIB*Vq^XP$$;{B9S$u3bF@j(EJJJNw#MhNL3RlG#d> zCXH+QP&v0S(?*u?Y3iEVv2d<di<6r$^sO(Cn#O-n9%Nf0B*y>8vSe`ufqP;GVwdCE zGo{^Aq~5t&xn*8{we^45%NADrClck=D+JbQHQZz$%yj=8`^nOp?HN~PA@Xe9rwHZt zW4?w4t=xGK6F>=Tmp%&TLy7o<sF|&SR--9PsCKj+;|k*c4@~=U!OIXzlN7pB8@ON6 zeTDt|-tm1QA<`$7z3_H(#>2^dju##ndl1K1x#G+zPvQGZL9;C8+-c_b{dDa5HhSpC z=x^(r-&=I>3C+|20A)g^<mQ`%8q~-bWV(ig1x32s7nM`0%`jDCYKC@+#Y(o>PnI?u z<Ja7Rm|;&eMmkrU%z<s(4HV*QRs9_g6UxZo*+H*07>YG|YxJj5XJjPUaWt6b0i<$$ zW4F?Vwef-HG=mW&dH^6^Xe?#V2Mo*b+nSf$jE`Dt!h<kpj5brE=V&YDI8on#e`tgX z0mukmWb(Bc)M@;=<ytJ68Ym<%I=mWq!y-Qg{QVJGuD9g?R4))zeX0a{5;Q+TA+~l! z3_sgOPjgT(m5#_{;@TQ^3nX50SV}zmy+RaE`oa(3WViDRd606ve^DVy3d32>Mo&o2 z5dPxuI>)SEb!FL!)B<yr;th|A;cm~sm><V-FgKcJU10UhA#^*e4Xs^9xQNY4i=+!a zO=RYcQL~kD>9T9_UsWd~4>EKPKI1zeUGhhQJpG2}kMKb}08|#VMDvKb_A8!{Wc2C< ze!*x4juGEQ)G6)K-O2OUw~A)2SHhudf2QAZRenH(1Y38p)egfRE<*4&&yw}83JjuN zehrUhP-X@^%GXFF>$Ydp>GH)oe6M?uW|WIx=Th4c9!gMQsQ3Fe69*ehZr%Le#&<I- zh=6xBe0_%V4<~}}@0mZB>mAG(fx%wAqTC|$8VRKU<!87>FjGD)oe6dvoNjgd2H;=0 znvB<4eE+H}T)9T9j3fkHfsRDhmeJfLk!B@ZML}%Eq<M!-O)OfA7pCPZMeUTmEx3$Z zuwWQ*ZdBS0zCpxozf`JH^a7FGiKU{%X^c$U*(^a^0TP{{=HeQHBil$?*j$$|=v{sW z03srJY~k<Q7Z%h&jjqG$_f`QGzpJ~SY~W<ZlbD(b*2*TB#|%SeLsCwz^1_kEogFEn zvvGW+%3(m{^e)|y%4}s$NK3rCI-s}ZV35acY|g=Npx@K-=n4g62FVOrpmV3xlj1DW zjnEcT{UOCbLkQNWMVBQHO)|Ogu}Et|T2Hv<45ER|!5Vg)O}@~}PNSKy{$Ll+$r(62 z*?^%g|7%8J-^6o!dlPCZc@Y28xlg<Sn;THZzm*0cV?!qix)#|7e0XGH8Npt+?_qx= z&)cE=Y+!lHcie9nc}{>x?}vdY2iGJ9<s%|E&`Ko<JaMINOxf6%zLnYVVYf-p*3WD6 z=fr6Q1v$#x&GVGfu_U*)3z8wI*IdPlJTC}j<hxk;72ZyIH+mUJdZh&p<c*zl^cQRB zKlE}gCZNmC=(fI#&|6QQ7(=ldeZAsV8t?(PNSHPJJ|2lq$q-1iNY>`qOqgrWN`e_U zb1y<U7E4*C#jTN|CJdSx3|T+kE$qtY5$E~NvpZ~F3-v#k(58{vmjJNj5C4_yY;bDq zA|-zsFVItQ&w#lnM?2#53182@C89J<p>55x5AJ6@<Nz|ii!5ZV`kU;bR;vGm`e`{g zneDUHIYUWUbUusIuC>866mhbOLwW^N@`w6va3g9|DhiU2NG_UK>|k#L`Djf^90c+p z^j*gN^O@ox5jFD*J6eO7w(cx3_e`#68n=#^d>uX%EDn=%t`=)JUH|giL$w)skY%ak zHzgoow^;PEPysyjIE7>mB|DxowN+==t2@S4aIuK@9Mb#jG69UKK42>Zg|Xr}9E=8p z;t1UBjz6Mg$}!Le2c&yE>WK}FqvaBy*7NjcE;K<7oi3$Dsm4=8N=aM<-@F~-k8#0L zSdohQ3D}=c$0LF|us-5FSg?Sp$f>G9FFT>PO=Hq{m4}#xfB9+R)-XS#pGRSj^#p9( z2j9`{K_WJvF_8*SwghaTAQ75l-7b%jDG27hk}btAx|H?~mDR%(G3kCxaSzc(VB@<X zs>#_C;nzT6(Rclc$EYlMw6IEV#>KD7U&_-3$AXtEM5ZjaORJX?pO~9GIOmQPS0Bgd zcLurL)~iRChU2f7xP#28KZav*$*d3%8|KHa<Zv&pJm+Es%nwF8!6{$|1_knuGQo$~ zO4@5Bi>NU2a@@@X$e?)IQ|zKg>N#43<YI86y_)SPKap?&%URyUgQQx5{dtv6^suIE zRHKV^v48fDrxu+sNSKAbU_bgGm%AjFUYLlN<w*dTs6s28^V!#!4xASb4O7ymJvsI( zgw!CAlE7Ph#H@2?y2XsZ#T$-ige$twCU=i}hqlHd5|preH8FeXSi$y!TyA0=OyGh8 z`*p;4?xP}ZkVX#h(v@LVyfrYFCf*ly=Ck<WkmZ+CzY%#zMny!|MF_v9W7MJ+Xl>(B zqzo6KcwBB8c)*~Xi7mt+%Q2y3=<@+=W5oCKf5uRLOmo!B>=}v(bwj_QCiWquQIPP< zOYtc6s*k4_cH<Wp<t(~@aT06|SdZxQpx<Xd^F7Ts-xQ)ukc+pg96!gRyzPDPYcZy~ zj~Jm{v>F06Z$cR&te6bbQhpi>>!?Y!=x2@=aR456=}8x3(IU4AV^|;6*%W}GSBveM z+MkeHt?yEy2mt+bYDS&<R=FrJ=S_+bI)2}cx_JR0E+)q-)WHH(lq(YWZ%hP74*5wC zF^SAQS*F=cGo8$bf!d0Q+*vg%Pux#&H>39NM#3AD=p*Uh>`2BMSnzW<f}_UjDTeAw zl>HrCwKRfcBUr{kSEGJex{VhzLA?srGDC&8-VHl@FzRun!I&BlnjNrFYPwlDk8Y@p z;0&9r6}T5oc05Q^d@Y{2^Cw0;C|{!0KW_@)ru7hB)?pR(c!OjScVYj4%E(DD9^-_V zv1h<w$XCEB`g&K+3GJV%S>yf{G17Ca5B?Y-xEd2c!nG&1pJDqVI4_B$ESKB>0}T`l z;ndes)Qw;Hb5Ha*QnP2G`&?jPR<cICF~GJ^#wo!#m)z9mWknI(f4taixKUKM;@tdw z&GQLiPW&yk{!DIv#w;!9?xM%;tucPBOlyp^y9_WaFG#R!4AHEUQPqo@M`{|17fmqk z6UcL@$k=Er5~JP#!X4=Ob|!;K;Vs~1(_%ydu>_I@g3d}KF{Sf$VzJ~lyHZf@ZNFXc z#>iK^a7`<aEH&sF(-@at7RTjzQ8zZOrSQvM!lW&TR>@H=v;P5`Yhcg_z_1njltloZ zDoLNs1Hb>e9c04M*iNWN$p8K%9Kz(-GdgWt=Mcm+#81D9YEP|!bZFtxww}xZG0be? znsqa6Vnj@t)nl{mb|F%+B8VnvC7eItL0aPw0S+8HB&%5$g)9@beQX=W2uzn<wwNBa z%+bm%mDhAI!|CJ5s!rn8{nZ{!d}ZN;16w$+Lc7!;HREbawel6t4GSd;b(*^^6fQ&U z%19f_;{+LaX_xjB56)zJ+8D?P)bZnZMBu{1RJo$a!A<rq#)qMtr6#`wU7<eJLqs32 z1a&K>HKr9!!VYxzqtNMAEr`+Rz#{LoLM%0-8Tf}ZD4Zst*nwHIoq33Th-?noDl2bw zz-$4zP(l-s1>(#fWw<#_`%0BNzzYP!qUS=iB>%c^5xXgQTMCA4Kc?(1Zk_yqx`dSw zM2Qbwohlkl&@)<qi5!tXwi>@nCpfeHO1{M%M_E-vkx#Or<WGhR!Q#}DqIBzJM)O8B zS{7DHw}VJGV&RHmJZ>wXWyFqG-UIIP7kgZTNWFv=+`#F)>^XQgq*r9Z&8c_S25K@a zlJ&YF1wOu#bM(}CS<6u*>tk_KEhfP}9cC6QN<;+&*1I(Y|C%1nMk)yxgvy$GIDXRO z%Q|Jyz~1CoF*a@CEyZ8qJlO!OWn-|(rhQ|m?|A5{tu7+n9}Ic_mO|)uZrdVyBdki> z$c=t>Kqv`xh0_f$D4ZsbeSH93zm=R~@~9rFFP?SGBDK-4?k$ED0>6@oXxyWGx(N(z zFX;W%6{2Ms!is^?^;*?nExg-3Cj!QI5t(M<FwKdsP^dy~0%xNA(4xl&+<$u>5AoS@ z4uYBr@T;tMegd8RL<0;C<SP1&!=ALuV9vjnyR2Ahgj<rgLR0;+{dPPUUu&njkUANo z-HbEV&{{*r+vy;zHvOXWEjRWbMzb}=;j=<Pr?)+wBrz^hKF!}m7^hpdly*{W2DsT0 z;JjRBtCKg~b^zG{%WhRPwO|-az})pEb2j6gwx^DVGvGaO4bDeXa5r?u&#Nc5SAV65 ziT~mvo7%~kVEAO!G;&Zz(w6z?>kZ}`PsVIE!lG`?x^`~s<^gEc!B_~+0fD4c#HXE& z0t+xguX-|w_<FoEfE-Q@CO|Fvuo`|OT%EIt#_?w3?C*^LUHWSD`Ugj)sNX2X&l3uN zN~wdSB`t&G$&SrkoT-usA}arsGc+8k0QZ1(X?2Lgxdha?+IF0IAH6AbNrpFLsZRC~ zbznGBVxrjh=yfKt%*40x*4!HT2Y2He9hS%dt+B?cLTFm=s&>9|bS?A{n>JC~$b%jr zHjlh0Z*H>9&ZK$pQ$`o9u}zfR!#6m$LG5&xJrkMRxQQjOu9IkhfDNX;4d#we@ZqG! zr(()$6=R!FEt-Ugp4eNIvv_X}$06|##<PE?dLP<ZA7q(y^@fer0xO>|X@QtUh1Z?h z0zM$px{v}^R3#5snz;crtF#j}0HNYsaSLuas48M=uhM(F=x7T^Tg9KLJ&_Adad2nA zW!~ll-MD)NRs`~0vE0A`;ur7muTwxd=j1^F`@Q|?d4*uKiT%x^CbbE)IRbQ+37<)s z;o{*`=f=`AU(iP4dqj&+qiDQwK{wYlmRM5_F!Why@RqvspyF@JQL`J6UOwk&>vPSg z>@Kb@Tyy(+b<6|#>Hr>i#(5WJVMeUN{gtP3qq{ZH;o<KN*A4@R*G1+|DP1LbLDJvO zj<$u#m4z{QKIe>kh#y*{+J`@u5lJ5#y3Tg8rZmjhO@%&>R7i?k$$v~;C<u}rU*D(x zx{$n%Dp-&Bq89rtB>cs!8!nt9@%%Qv$4X!m7z2$fYAa8i%O3MYU2*B*!|O^xrzeTD z>A#KT%VM}Zas?kOw@bM8YC1_Uk9jezYRfUw>E#bzV9%BU(Io~?^`>QJ9%YrZ`w&Fi zW6=EohG;fe+zn-|H%R$dQ+9VGDVK6?#kjiKhxvCDsYJgMAfFqT7eInV-4$j)Lw*RN zvmUElI8UW46C2mO9i(S0rdq8te3xIvdi3GM;Pj{r5MnyN<wX1>(IIcM+DTgAXj`qU z-T<Q(vxX$-NwK&iuQm#J1qn$=9gD=$_d_kX1Z_FjBb*4=HPk&z<N<z}Ye<}GV6!c# z@85z{d(n>DNO=>1yxmTmPZ3=fq_Df=3%ETa)Xk}nE@Z}vA3&NNvbjW3kLHNu-ypnv zR%X4~yz+)2k)kXCmu~@7*@C4X{4QD){73m?^z9PyD=VKmIBR4YiY|*;2i<3O_ovtB z0#!4!p9|4Yh7M~K*L9!lP3y^x=p<}*;M!hKLQ<!qMKF-n={>RR#~;Fh7hhEMCl5`z zf4cz|KnwzJKYxfekefo?ytgsWY(@A@tP>B**p=KHZTCJ!5gy>l!O&EQCz@gkfpa1; zTPT#GehJueF5}noyim@pHYdT^w|`~4Ep0yJ%S&X3>>1nAF?h(M^3pIvVTU~<WNHEI zcjTQ}@|T$%)1YdaC{{f!`>&~DE0&QDkNEt~bC5~29|0?WS^AH&f1u2b5qR)62jQ~E zy;)@mi$d_#KZzt@J(vU1XCLQ5rWa~chJG32I2aj+&n^9K=Y2Tsg{~1-s`>QpdET>1 zM-!A;6_*7V-L=Th{H+wL)7K-HKN5|o2?runjBzzc{XGGbtr?DjcC*oqo(uF?c~ZrV ztRbx%`ElAENz2y0F5=LY97S!gO9QbUUz*3Gm^sE+)~w-`(1>9&_IJ%Zt;$#RDfI{l z)=OgaB@mwALsL`ydm&gFEWm!#PGy*lGqL||c`F-HmU64MG5;OuLO4n<^;aSDd|i&0 zsUJ!`ZU`dM26G-u@TY@tFGZ$9{PyRK@f`T&a~$j*3{Gt388laH(UqFLQF5@6l;<T? z@%=<N_$vENC{0DveIm)LRXoJC_OndIIc)XWrwO}L=sa(!IKi142?rX3;QtVsSX7P+ z#vs=3iCmn*DinoAC;dNk0TUNguWg?HL!pB=mQCMT&2NW!02&Cf3Pf=R;OQyb@(Mzi zPHrUbkatj8(uunQKa3|z#b1Cc&6YY>TbWzsv<;{6-dZ;E(f-R9<~S&Q6wOv<_~BTr z?V#~dej}DOSC5{{R*+%i2nz@wnRGmzpETHAxh!FMkBv=Tt0S3cF_*xsXTT%`-RqiD z!bAbqU>$rJ>j{5aE1!Aq?pS&N?BBKF3Po3jnXtDY6?+k(A9O9AVx`R_oCH1YFM&Og zs2a2hP}~OMD76tT>@Dz>hBI={4rHu*f8RjE&w6d{4v*U{E4LvKEX4TJUY8e&0QRn! z!!mv#AWP<VuPV$oE>FVt&g!A6oO0TiJbK9p8E_gdRpqp4!<A+l;DCDx7Z0ih!w4=m zpUh4?s#5NruS&k9)gdG_B&<ZDq-V$1c$hsVM0-yFhe&_EeiW1)sVF9(q6{$~3TYw) z(NjX9>@<8LfbOv{!l>a|S*Nn$HXu4ky24InpUItst#m@0TsGR|2=L%i$t-eSmeVuC zc>mk=LB4uU9|74R3R<L=i__h5YV2e1WyQNqoWtZNPJXJgOBd+p&Y_~YN_WC9YouM_ zS&b4lOkAr-2uT@}U+1I%!ktu=7KQt^ziGXLRyEN_4!TRonwvCkuG~Gk17BxX$N^xD ziI*KV*GLQk1h`K#pKk^%xatidWl99Y&99Jel`EEx>~mRi4R>v5F)sXT`l#Gp93J)G z9eig9m`eL6DJKEBsCP5Dj#E}-IEtet%KHVdDf<l{DLPUT|Mh%J<{fKWd68qX;L|2a z*<06x8)#*DIyrT6CejUV(ww%0)pYJ7mg9-65BmzchGdJ&cy|gZKaZ|r^$}|i28~uh zt0oZ!ic*|kZPEa?fJrX!P>qta*bF~S_adyTgPNdJYM}6pn+Hi3MCumLzLQRzD4WS7 zwEYoO=T&^N(s42Vr`Nna&A?w;S7L%5O$+Eq6!(IYl3z^N(dH$p8vfcdEpU)@DjZf- zbXTz~ZV5g%O?JH=Psx|{GCw`)4@yWpiqsa->nKqyKUgUl;OeeS455+;i6n;NUU~)l za-^S}$GEJQ!9v`CeRNMubQsJ6FC5SRwxbYC`_9WiInE(~C<x&eVPd2}qld=M6B`N| zT(lc@m@X(xHb<Xvg|R(R3|v4*(h`okdU|#B0((k3OCm=;(}x~t%p%=y^2y(Uvq=Yq zXDljX55FMyJ;~>#i?RQ))tBr#stC^(h6kb1?BW0QvO%+Vyf7TCc{Jb7E>LT0|GzjA zc9SGh>Lw6#1*(EK8-pzp;|Mh&|06HOV=Pz&-)(w&u9EuL+qxKt&FNFfhm-y*PHcec zSk2HzW{pz55C%BcARK%wJjXi0(eqRiDS287wUDj!lOjj-01rZ2eLcEQ!y5?8gJUlb zEOs^2T8q)F4Q)Yty~?WHDkN^D6y^5<;GYJzSXyIx_%aj<rL>Iy*$efs3X*;a#;w{h z>0Xo0aTqI{JB8m^Sn2^y)ZeW>_sXy+wCRqy2Zek+XN{3;9&e5-P%rG1dhA~PK%|Xx z5SvU!J^fBk<gaAMUJX9V#h4QaxQS7i!;++F#&3Yc#Ao$SLgH>S4r9FNliLdXP2)IQ z)gB5OSVI!7J|ZX&0vD-lx|cRQ+EX+pe$k)(h8L<qaJGZs&7x%$Cd&>&>G6q~41$;{ z;6?MluSAKXso-|yGyWUiC9TfgJ=as{xlxA_yZS5$fhwam#CFrZqwtW-G&ka6v=AF7 zpq8P2gN3xl?>hE+%6F3g1mZn6T7x*PWT<hO70(0i|3g9+@s-D4M3HKQS%HH2Elvr} zwb<$e*^tKfJVc7f-t2h*v1FK)@6<Qe+pt2H=gOs+&Ee&MhU42BLZ=zQDEl}8VL<c+ zUpI^j{5^|=c&K9XAr9t0C>kT+eGmA@v|sMI{kcN;Q7*=I0cJx-e^-?V+-B_u>6ODN zK3@Cw8`Zwr2V$53$|^P0tXu*fAhm|%=nGUY7RR8x@gATJ5pjr2U0x0YA<ni_FFn#B zjcQ3VLiVjQM3C1c8P_T8ytmOhJBw4j4e4fndT|0dNX)>d`a`osqq^RR)5X(E!1o56 zFbo&ado?~SkrP;LM;$x)J$G~l$H#B{b7xHNrM_v2DVT$CYKOytE^5w+HE2Uo?Rw+? zlOw;!`ac|7)<>J7r|HM!^XWa*g)Zu-#`$gdpkGnNxW^z2+%}O*$*;Vpr+cnSw<@5k z<r`$MsfQb`jl{P-PZO>a*We$pUYmjceL%f=Ow#|>8Fq=B&X-PC$D#|F2c=*>71HF% zngSnLAE#3lfBiM0Kxe#skS_*DjUO>9iEAAKHA@m(mJ`E10l92Pcj3)RH|Z749LwrC z#$>}KUHJ)gC$jV%j!9-!r^*+275Zui$LUEMB}gZeXVX|zKaZxKE?&%f!abde_n;zr z94mnhEJ`tX*EH6T(bO;t%jybzp?Q$_l-O(YX=dG$FyJ7q;G)3uDj#^aBV5Z9v%8*0 zE4WdEec@3Hc8${+k{w5=_&TG?QiEn#5d0YK7n<K30IrHkCFYtN{;zJ%9uX>uOg<;P z9>C8=TB>hyR;Rx!>?++TK>wpUpVOU=*X);ICOrG$m}MLm5cICXHh~<466j&iZ^IsL zk1w_r7ZhjG2wQZ;tH(b7`;(7<Uh%xWPMpSrjeXmZB|Ei4l<247i&Dks$EdRVL4Hiw zjoEPDBLKzU)(?H{ljuWuDR<eRY<8(sUgaH9-RPbC1C4arvDd7E4dV%r#EZhUh#oeg z?&Z6;rEJsLw+Mz1PIoqauikrZirQpm_qfwZSrBGGa0AC4B8-MqAgb<1%nha4jbT`P zlM9Fni~&Z<^QI+Dv@x^O;$TSk+vy8xjd7HzA=N*BQZ;lG26y2w9?p!uj#)fi5wpXI z@^`0GffzT^I`t;CjvDamN%>)cI_`Fyr>;aDd4}s&K!eIeDg2xwOkczMiD4dq`~*t0 zl>Bmz_S?ofeXA@R$hwW(*~LNu*-Gx`8S(-iQ@P%X)e9NWC??921_=YxJaYtdHFJAF zEFyvtU#F;2q2G`AhuQ_RJC$<1f|YCKo;aC&<<yN*aIP2CV!1I)xE{B-Y%A>UeqLQ6 zQnF4O##hYq(LT`JQ00yTgtBQ))P{`Q5yiXz;K#wHn%4}Py%(g66sdC<go|m(?h3d{ z$j{xdl~|w-FH<w(``8A10j6;gsLDDrXO+k=1<~T}W8!0J^H}HuR#gw5`?khXp*7@R z#V2$NL$`*J+yn_vE~<+~{{=@1)HtOx5eecBMgd<eHKl*_J}B1(e(Ai}zJN3-TpGBw zgo1yHSO^wyJgph0t?&GGaC$XOx-oBYaIRm-R(vx#w#^29p+EIR>8!!okz)(k`OL=? zCnU6^35)$q*l@SNHE7yNxdq!P89>^d-E$U+=y%C(>)f&1lGe7Y@fk4zbvqMPC)7H$ zz@JO=!|cGn9dVCFuY2@`3^_bx%m|4V>Jq^?B_Lpu=Nx8Rq{@9#O+R|P;aXFJ)M6R7 zBUneoks-=_<w*P^r~bK=isU(!as(u!z8{|fKLNv^7;6T?6D8unG13*@8W&Ib=EVoS zG8460gE?a7=whHlNw4l-48?n_&%JU@-$extIs${CEerP}`G+zXX?5I9A`Ggi1O4uD zd$`)pQ+`bupso1JJY&pTCg-Ze3xGE_NTEsuDu)WviB3LphSQjYZ#Di_V{GNmL{OMG z&Dy<U9=5HdI@LW+0StPBkfV5XHp30Ylw4I^0et{?Q<*@S^jTP+^SRoNk{FjjLc`Q? zq$bLx0s1T_dI~Aj*TjdzrKn*BSZQ29cSzEBgmZ*YAVDddy}&}x&s?#l16YIH1SFUC z;Y3*oVT1q&H4=Z9Zmk*B0KCXMfB>=i$oeW>{$f^6TbAmtrPkJ>Gy;4ne-nspW&{Q* z%Yty-x|}BhC#Tc{M3)n|htenW?(xl(QQtlqKa4SGP^_1(aT0cW6xud0*?)CA$9<`G z_!tswP;aiO+LJ0m97Bl!OI7+w5QLjF+{F>w+~0HER?XkSa&n^*mzffjPWWps?tf9o zR%gVvxqxmdlWaQWc1a@qQiO5C8{<6FREL?27<N)8V~uX8vZxMJ=$L?$I-@jti7^EU zd)dGOyCPVo6kZ#YYq|fU#Zw}bU@^Wk^6oGomyk9Zt|s7wvvxB~J`H&sn)Om#Ga1r& z8?nkkc0$@lvE#5GrtIQw^>+eEHH62rgtFTF!fK{~&wMK@%R;L~oe}*k?If52a4Jmi zKS=!7Tz&aQU+Ga%c|>6Tt~yoZAcz`E$bL9@XN=Tj+<-0f7>R;9b=HALi;)i@+jjYb zqDs;{+a8kt%KNEx!c)7Xn<%UnVx~W){J`Z;TB6KshgbB>kc5#GUj4t17ww!?a@wt{ z^=g3^b}ZLJSNq~UcXOrL=>{b_Z?w|)n5$oun#E?HR(&f#eDsRryc9Y8Znz^mY?DF# zLeVr1-1P)j+o_8-EL|P`r-10TACEk<yND{N^YFPw2Lq&8+T@EBqC%?(CooC&QG*-w zG4~Un+-V&I>y6U=W$T>-!c4689{B!Ft%;%Kxx_QTLv3iua~A+KUU(y6d+8SbvTfHO z79s+LXOdN*04B9V>dC($jj(#^RN5F6s-%m?(5Z1Aa+FT$a<c748YJvoq*%cIniRS? zrgoDqeMqoRNMvEZvK!0vqm?5tx2s&35C8@(Y<4diTj>xCUm`fa4FX&;W0R1Lw&pp6 z<!OopDtt<;_`3bDEJt`|g6todX?~k_j<fo>RDK33j2%E5j2_Ehhvg|Yi#w@?7eEP! z@(uDbdj)MjS-1hgeK5-iiNNE^0N7uYS9c4unoR1aE+*O^Ht<Hm+^=c@+FQGY$5a2{ z0ATI^uCzUM=Wm4d8xEz=J3$;Q7zJnAqMlHlqWRi8BlZj%=3x=7W-<5AQAxvnm3ul- za!pPb4Lf!8$%#+t5HZfiLVOA2d{g5C!T2N{Ykd6U1bQJ0eK^M*#Uc03zYENdJ8^(P zl8J8Wb$j=a-(X4}M5>Pk0UJR5Yf5Sg!mz&c;T?X_8kYS%PA(f)ooL4TF@x<SvWtHd zM~%%?L}L(}e4;`EbNVI4`)4JUq?W<8LT-gZth4AOj<Bfx1aF3lX#PA{F;as0Ja+4N z!2VKF5R?-sk?GHxv^dz}$~@e1-Vpp!$+qkhUn+MAlt9uM{5pJ_<ho>%%vdG7W(qzL z0Uq(lcf?MpXj5@5wj#~kBQ5+IyoyZB&!aDgB0YG}-va*>xHr2AU|aN@l14C^6BUZ8 zM7I5+w64#$f0s1B9nu@w0O0l2J+ih#qTe&oDNNN&od>_OL@)njxGtC;_5wA%P|%Zv z2KMit?6tX`etHkKjBQ{;fO>b8J}8qx?}|~ZjNJYa)ROdT)Kas|=rP_K<%G({>7E}6 zb@-zwsCnP0-X^M6CiiKoNY9)7+7mj`%iXC{1$TmhF0#lNliZX|ydpD}kN8g|G~vtA z0g>SGuf%%NwNhU0+ul|5y-uU+wnNLxg{{?8utk?N8oyt30S-E@x=6KUW1-)SEm({E zv{w@x(Cuw-d^T4v!1CSnnM|P|_P>Gb&18HbQA}VkT*;BL*gf6W37cNgU)izWs-;dm za$rY_FARL?Z9Hbh(tEwr4S>TBV{l(p1p{Kfd^@`9#b85VGU-51aKw&esJ%P9oIYLo zX%i~@L!^AsY@g3vF%Y{XMgi1D(a~YC@IP3x(g2}e>mm7&(<~@3w`xs2E3SK(2&LBi z+MNU}@vDv~DMaX?tX8g}W6ya&m@Z>XP=)kxDjQ%k!sP5o*2v36rKk0-i*ox+DR)m` z*ooclN|lpj8}a{DjB5}sXx*!RcZ}W6d5{y~NuIJ!O<~}LZ7e5Cb(`-nJh$0&Q{n#2 zEFlD;%QCU_O^o)KwkH<>zWg=yiw*l=gPoUVur4cI><P8Q58YQi)fS3)cUfTiGKOi- ztj&3pFw~M+Z*zVi!C3Q2nlSwUEC?&Q1eb^i5q=|So|-|_B#>b50rMU>&*T#dc7<=U ztTNCPeBnsnr2R#!dV$J5i}bce3hJUod#>p162+zcLa7bBvR_JK$$tyZ^!D!s%U5m6 z_eX)+2Z1l1Mx0gWA(UBp6d019K~k0)PY}3v-fena>ZZkcN_pi{0}C0BUi2$7)^kNc zFe7JogCHx=B3n`rIDb-CCh8vtyjYTf(F)Rl^ia7fUd7bB@Q7j|C*XhzTXQ5x_Qx!1 zm{<;d1k?xO<hy7~7@_AHSXzJ3zC0=l!7TNf-Eg=*E@m(dKi4HA_HC$TK_WEbT4agX zj#kXqLxPk%o|X!AGgM6o!K!`S^t{+vf{ArJCFIBYs02*LW-Us6e}qVf8BS}Z4-{T_ zdr=X(RO1d*@M<PoQT5m}rD}|e=#BP9Z_sy*D=PB-cT<+jEkzGF(!mzb)YS`~#r8B8 z4@@d~hB47PwEm3oVi2eVFk#*mJcE86YNup<N$%4V6M>(BG5spzbB^isCg`dnYx<E9 zA*Uo9t)SL=zShdtD3WU#nd&@^y36ft1F~_Dj%g+*!ha`jfZ*{9zCTW+?~~KbV?wSH zk!|o^u~IsAfw&v!bR`zwEqp_7r`Q_<YK+#vMQ1@Z@_rRAdsRCyj>&Xv*D!*9LBN%w z0{rT>gS3w5sORf7AbjCEMp(0-inzmNgw3;PEaaV694{vFN;wm}r*MW%&g1jOuTEw? zS?EBa`+M&$+Uh)TsKz0-@hqpfX}59%&?k$U9keHELu~!S{4f2>?c@TwepS&r95M}A z=q`70+v(4Qlo&FWI|ZV$UNBF_Y-xIT6{4*#7k&@759-6D(=Z$!i~AMmxY~=LEo`Ol zV{_i&-%4F3p(c;G?bK_LPmJ?4y*=@h835X%%W;4|D`|aUn*axZeA*8*O;bCu-<M{D zKA7B=vr~l+_R~P?rK0$%b&#S2iLWgVCC3es+^zm72@_rK8YfQ*wRpw?vw~+rC(s`3 z&Hv=;3?6w7VVuEFfWXb7DC;bM2Hm_gb&s7vwKDZSOe481=VR+Cc}=o{Z^(QEaQk~u z4k}XdqUB@6&FsXU_R2eY(hsydbSXs{?N?Nb%Ty#WWAw_ufWSDlm9rE0I4W-LhH`KK zLxp?9U|gtSVYz{#S3BMh57mD;B@O=E9Lu-E-~uab@F)LmS{*w*(!Lyx$j?fywUM8~ z9@cJ)^l7w9g`qKmr{r+Sz0zK7LlwYR`^yoF-U!+Mm}Q*FJHPfTQUw#*AnhibVgygi zMGG7uT`~9UtE-1m=3`20xZ3FxuF9SWywT-}Q)}ji2Ts@O_}2m_X{iYiJlx6yNg+rj z_CHCN;;#n%(B<^VF!N_u1nCKrBZaxSb@1WV74Jv9cvU8HaJTvp8d^XfqNQfbuI22J z523S#mzDCQ$uocNq`BeKH?x>%lp=VSUk{kEBi_jZy)P6hS7a8*HEZiBTO8T{b;Goo z>S7ZyYUn<sh;Z#fq-Xl=)zBHX!<N(XK9M)vnS2?%E->XSR*af9R=_fHhV8IUP+?^7 z9E4vTOn;-h*aerYi<j12BXYP7^8w%7@fQYq*-j(_m4PLDnP4w+qwD!ym@)v6Ya+tw z=I?5J$n(z<8KnG_bnu?sl|s1t>K^In5a(W`jo)1b;$3f~ckExS#k=|GD?~{Sz^Fm- z&K)ivxX_uXOW1zdWBFvE0(Tdy#EZGFh78_zDNM^)cSMP^AE3?3IN|X_B)oCw!kN1H zYAsIf67m4zfEGC$CER^$wo>Wi2G7Pr+eL=!iOX}8eIt3^;bAAqhbYYtx3eTd5ql)z zcqY5ANI7plPB~%<%^R?gO7mDs068SOIk4r)h^=_f1aA#y{F!}{IF!&ytck8)<jq;K zOKvuj0Yhc}2~$>G@;`_D=tEpjc;?*?^lJl>;OtAyMMf<;#mly`Z^ag68{yk`>3{I+ zTYd~i!n!Ejg(F#jLSrgk^fX!;<3>t%8Hw85vv#U1BQ*-M2!ZsD!-b`zl%o{>$EIia zuQ8;i2UAF#wjdfPnda6+Wx+ZxEaOxfus2V5SR-+!6;5fn(ipLhb%L9F=6)$B2(`&o z_`DHe-1IGxWqR~x%POvptYP5d{YkvS(^5H@!52_D-X_0cJE(W{YR4z<$9k1y=r3z| zF2&0W6%EBUf|-P4+C`f2U%z5F2@$vL4aEak;a^JmLsgsF-{bR2Urx%}z&h9pRJ;1e zbKCe6ik+BodiB4Yx3$gSUcsf*W(s?5(PF*-V{M>$R6$bHoIDq^uv4#tZ{%xg^Dk#I zkxvoJ@a)dLREmEp9;7kDAzKw`YtgM>^R)FkB2D2|*Lh)<VAkGx{kQ$G&ty=x*DhX$ z)?L?CHZ%yv??S=A+>8$0*1k99piC~OOgjJO`+W%<^jqkP7-<od9TPwgewMv3x~l%L z_O?<4#ES3H_pp4+K3gfgsw6B(!|BNHn!k)8qVBA`MEqJ~5?Z?|Ty3<-yia^rg@iN; zJzV2_Y)xInIr*Wp<<Ml$FYs`XZ$k(645(3mf-lJ_nOGnnp_hV#njcCwsz+b_>8^*V z7ExgHW`z)Ne<g@#HwNBYa09<YqNY41H;*6sP~zKo`yNrH{<}LJ6qw45IT(govqJQq z)S>4IGxfI{5G36>63kU$Y=~%HJ;&NBnPAR$T-c9Z`Jm}8oA7N+DGYPcdw;<IC0Oxx ztiZ@{&$iIRJd3Lo|G@2%lW$m>`=BUHU46=ZO?l?26E1*u48dBuG-KW>W!uWa=K5~t zR4DA!SbQ^cpox99O;(qAR>+PqydIxyEe%Ca-yHU;z~sNb>VbxBC+4s3={3ZSuYSg^ zX1}7L9BSO4LpqrIo}svX<N_Ooy-Dx3sqlT0pZc)Mgo>@Q4ZjW}{8c^lOuoA(+5l$a z9zdVZD<+6*A~5pye?9FU4hvZY$!POYL0%0=gx>qL<)vFz%mL0%7eNPFiANY?F^!Al zXLkYvcN*(CRva$eZ2F(7R&ValPUzjDxB?g~rc0Yn;VjSfER@fW(aPwNR!5|NB)pgh z6%+Rcifg<_NeIw#C9a;a9XI>m5px9-I!`X7^QjUKHpPQja@|q=U|bNaXieRbjBH4` zhB5gVO*ZjFI;gXxtN9*SB$s%5jIkE*`gd0_(M<rcgjWYEn|>pgcklC67-NXCb2LsG zM_2On`>91SrQfv|n8zd6y1OHZwIGf)Bh`*{+qr!PE_PcG>Ki$jyDjaiwt?Ep?I0z7 zrCnX`kVx#G#IIh~)<xA{UG_9Vk}`9+p@Fd1)>)0;o=L8l(1G0F*B{e$DgAcs+o2<8 zsrIGva()lK8B--ohFTF?frhE(71+rHTM#Rap+)sQIXLChkahBcjQOT!-tusEWfbp? zPAEOmydt|ktvks=e<MXUHiqtkC3D9b7lxg3X}rB`mbg*bAT@dgcO6lxjEt58IS~uL zm<gBm^T0<DOeguau6rjS|1ZbSN^$S~ekn!+FV^w?ncXZYPw#E^=0ju`XGqv(*{KU% z0fQMM^3OrTin^Z2pMcySvHs&BKQL@$ib$5gSX~OG)MAL1*hvf-eVjcl4cH?ai2PoG zjlY~rY7^nrru(mP9-|GwteTL;oTS}L+?KGWOT6b8dSvC~Tiy=<mu4||$+YwrE<F`O z5;?1jb|;aLnsWCH)v<1YJ9RJN<YCH*^&KW}n9aw8Jk8gD(D?FakHVIemDiy2o&yyq zvISqE`JG@?T)X6wN@<E#KJEkWvpWt<qgCWB>UpB8{`V}x7sJ%E*IRWRz<J#(TA`Fx z;Cggei3e&7mUE?aa`xJ6=b*4m-?ZGlBS0)>%>9r;66Z~=s_|4LC*!&Z*U4SpU5_kL z;qh?rQ;U6Va`@&XSvpmB`#kyImUd2gF4~}!2W_~S-``;rWsuG{A~<=kHvl?S_bS4z z{)RfeIx`oX6jhX&K?H*>7Y$+@{2LHfI+LK=Wpynw-8M7CRP^<?JL<<c48dW54ZzC1 zujgeNhb=#oL<B*254prVEg-dnn$|o_TBG<Dc7d-0^>D(tlK(0+{W-rrtuE6~%=^BW zbdkXmK5kD8N+M)rVa+u>;b%+PJVDoF?3=U<Lju5U9g1YodLm+6F4z0#`nWIokL%7G z3A7!^{7FlC>&zO;LNHjmU_v|M0oN<dGHw}8o&+=T2vth@M;8)Y;l0{et?`wPi+**Q zVV^N@d`5=5`gIv~ZQ|g{@ssc^RRD>*Bq-^g{4_8+IiE^|CLrFsRgj~P;v&!$Mc(&t zrLM;U=60C}kI;Di{PcBeMj7wJ?bx~MH<B(X02sOKJhtWR1-eU|)kmnrfDhf4Fk4{5 z>P^nGpu1`E*VIoE8)4d^-~8n#$v|LQnD9$28ML*_LKe$8q$fN8d2QV$os?u%4D~<z za8&humXhs^oB0|S48rt7aHFy-=TJESeRlz_PKCfLHa|m5*(P-eb~-Z`N_|+!r%EZa z>45<D6WCQ*)Bv@t93`MbQB+I2-KT^U==!iMa!)1QZpis@%ddkmC183f9DJvY_pbgZ z4E={PLBE@d(VNcHS|FKQK-C}Qh|JcV+t<#vo!6Xs<wm)sj2`D9^nC_t<7#b@-v^#A z?kr2>Y*($L8hkBD2DF>xTXG27wn3FG!rCtQ_?%adI0)cGJ<9@=D26)R0Wbyvm6273 z`kQhvJ%lZ#4SKVWLJky63m}JQcWTs}pYrk<fq!#rmS1D{Qlt%3C|1T(d?-RH0r$v! zM?em~ptS#A>e@H0B;}%(Ml=?ByOfb{Po}aCuEmWSiiuxA!KxT28jrO`ETl)F?RM*C zK=YVXoe!s85a2<&DcBKO-|6I-bdz(sb;n)Pb?uj2Q;&H-ln(#g0Z=?)cQ-gU!bplT zMfG$?)`|7Ji>TzZ+g-%w-J%$K=5Ctlk!?Rg3zY@wJk)98@HQ_Sw32cn_O@>@i=V(= zIZ)Z}p`eP4kpD)wE@yi{4Cj_e57yG+<Uec3j3s(kROdgGyOPi)V=kgvW;$NR4~F#S zOkVp@KqSK_PNYzS8)NJa>{%`BoveIaOFAE-ZL|K|(_2rn{4Ebo6X(CNs<X43<21tP zh}Z46$?4*S#^g8BalmHVnt)4ZlL34-V;ivC$nmmeA<QbyIZ}&VfO_e$%hQ|?DcO+; zU9kOl`pUJT?{err3YAz?GE%!tb3=hn8i@@gt)8p%bwM{<tIdTtMgJWwpw7A~Hv=yU z_*Ymf{AvIy4(A;gvZs<+!+y0E>JOFKnVfpG?5ccg@yhZRokUyV?V>YFCo!);j}*Yd znW5A27B-wM8ggvdHqSmzYVAws$RGEGvT$C*%z#Dfde2Q!WzDbqFz+DO&AoslRt6!! zmH4@C#mAvNH;Uq6jKZYU2odj4o>UD0v*pmQIOBn>0q*7SRM<nZrj&Ws;f|^_*C@}g zq_NKr^X1iFrSsv1fI$IcWg=*d*G`R|jUFFu5C`>x0%3X6Almu3P3_3DrMJX&Go6m* z3T$2X0Rp+XQ4b>afn)(z?ThB0y#7RdilHWxtRDJI5^q(EW%_)ag->c$p3#Jk>(F7# zRjCTwUD{`ol=vLzLHAFcqm;_>#;WWVLP*!WvxH)rj-fyr?xQZ(%$gK7N76f8DwvRE z@tdBTNj)xA^?IHVx@re1Q&0N&V8-3caWBP2XK4OrR4Z*F`_hi@2_2Rbklg@H6lT`c zeo7Y+r01prO6-(dto<lJph_I5<kB9Lw@UcyRKg6l@#4ZO4CpcMfWY6UPA6w?6oSh) z<;11(Ij;8|&~=1p?2W^`Zbj(WUgrJbuPYPT#y98r3ZlUpebY5yS-FQ+nCERetOepB zv*&;j{k1v=yaKe5fylsR!}Z)|Zsl>X<At=~%HpeML&7Twpf9?tP1Vg6nn`Xw1^b`G z*?yQ^=P^@`($}n_bCw@VJk(Fvs=<}ZPre`XniYB4&GF>1g|6VDvQMnM6GLCa@rHT+ z#RnXV<-jc=Z>6WUAOXah@gA>$>2|{wwPa%T0g^d%M`oeCT8;K8mnBesMOzo3M617{ zt&lykEIEsU#P5*3#RxO(;ccegO8_IC;H_XU!gQxTJLcn1=jrx0Kuzuea+XdV82f=Y zw6;83hx4$m3D50KxVSP3m~?WQzve4Vg~bl~hw8peN@pN^8L#uh(jg*L>1dy3m{S6R zckESBDr{{~55joN<K_9wH&__iHd=wHw+-6er5_nkg8lv;o|RiYZiSXVw(fRiiAx@+ zV0POlxs&Ul$(uYaTF=$EAuMaN312wi?@l?9LNJ(+U?&dEGJV{+rVAV5{nsbR&zr*B zxlJ=t>f-HGl05KqYBQa{P`slKish|Vb>>V;X3_(Pt11}6E$=pRjL@T=LU{<a)Q6zl zp9VtPCNF`Mup9f!euC;3D(mzbm;)e|SthR+$v^E&qvEoAF)**@{JAT8Ztr58mwDUV zuE;}UQG@sFLV7zBMG-^J(JR?M(xAX~Fl>y7wZqZ)k<tRWtrGrtzdZFh-ZBr&iMGJR zm9j+i1o@75TZi}euTHUpbF`5u(n*V1Ey?^odj0NG$&dqw{*r?&9+#9#^7t2ys%Enh z<V8hhKw*J=qv$}`1sQBwAikRV$rf@Vc7uZyM@{bM;QC?>j;`pa?9k}<Bl-U|(tCz- zx*u(5ST+b({gK8+o)O^1m59((@{0HQW9s_x5nI13oYb5c(=3vkefuec%*f}PmFnnk z>VWYfXa2|XgR8{)H8qpSfeEabn<bbbUbzlQ6{cGEp+eaUq)Nt{ncE_6Br?1#$W$1s zc$Y;0XA8?5i>$tjUC<722nrlrq(n3y^rmgou6A3R%H$aF6qm9CQSVeiaQMWO`Ux$U zeYk>MgOzf5#K!7T5svHabSJ6floNmN`-qDM%C3goQ$g0qS(YiCp9gxgt(|Usw|oI( zIVQ2#dmB%y9TQ*xO-Xln8Ib!YW3;Pj2o<Bua_V}qrTQzp$)b$HO-p}Mu~cYD=B8c7 ze?n<ARWQN}%|W3jbzDkla?VY(mHL8YErCdUwi@pN$fh>nu0+#!#V{9OY?aPouFzwo zOU8^W@=SosCDet(D)J^|+T4=ZJrjs|Hr1BA`PKtnklWQ+R+bJwN@a3=We}T3NrHgB zw#$h<IyB2c^d4Eo)?)6j);88waLoMZh~n*rFMy5$I{jp{;!VN@)+^#8OA5#Y_ENkq z%YOds9HlT_k2RX5NMw(cUG8o=61gZgF62WKBCZfYyW7OM03qRFWSgbAA-?kct(N}! z0|}b4{zOj-3~c$IXV}83Z4LXL!r@Rg7QG;_)WU|327azTkw%(%j&}C)_!^7%Hx7ra zz2ws;b~PrtTbSu3Ia2K_t9(6OsMNXm5ke)1&Vynlc$!@NY#`lKAoP0sF)P`A3Op^8 z3Ll~|NTxTpjd$y7`60Pl3sS>x1YSxZ?kAWotm&Y)nvLT*DTDp^=uS`b2b%E;(-MH= ztg{SaT?J`Hc75<0JcgY`RZ~1suZA9?oLq@F#q%V!L@}GI#D7>ij&h#fKM5n$eo4wG z^}vcHHX(>?+7feo?JoF0^QP+$AyX8a`qQVQRil(<9tM(GR5#6DI>~h(HwSP>KMAKn zpUNym!>X%GG;0zfLb9>AD9m=*!Kul1+L)mzvlA~5T)z`rT%?9Sx~r2Yb=J>GOxoz> zV*6AxFoQU4u#P-<^Od+I!`i--c~;}~r6&)BuBg2owlb9W(^a`K&Q;9$cI^fqbEa+> z=aRSuBM%BxjF{PIeD!tQmh3W&p6Dz%WBIuxJ?&eS{Mtn|r1l^lz+@b)dUvU|7d(P! zJj@O40bhc3CWPowDX@&cYKYUHABlJK&LVSY?@(Ty=OH3aMQhqop1_SYA?&o4Em?yI zY(;LM#>4<@mUy<8LiNl*niY*`$e&GSl)u>*g72mP+x*KHv}+#hMsirD&$Yp4KJjJ1 z`~bzgRPHpPrUaS;%H>cga%N^N@X{vcYoRYI*#g5hcEa@v-H$+1cvz+48Du;&*s9yX zVq$}Wk3nb~g{st<YqE3d!p>-19f^lxnDzY3m*#Pm8I^sc?nbdt{_7ejV*uF&E3F`! z7i2gt_~wcnmt{l^g6?$EPZ}NpFgz?~0PCJ%uePRtnWkk>Cz=Otr_X2tq<k}k>xKF! zYhP=fSTQtqHqr63h0gqyM6|o8R-kxC)XxgP59nlpedKK4RZlgK78oln%gHdFECtPm zrzWi%Y)K~8VkS0o>XA=ZR1y2?-q-<HufxX?X1MMD{&|vXu+K;A05YVRHC32e9K;X* z>e_Vg4<5Z&gH7-p4vPLy)JC-a-DcarwykgLafl=T%}REzxcSZrm{3Nydg(!nY{x)s znZG5e$2xBHapm?lODNr?<c$7`r%gajV%~IhmqDo1<WUls=P~*@KUgYhHacU;3JnqW z40g?^foCrPOUt0r(vEQ;v^xK&GA&p8pXi<EnUuH*ygu@4SlPp|@rVOgK>JW0wa9z< z_>9HSuNz-EkP8aFAr>%uuJhpS)SN>!nNDcOu)HL;3<f0ss>f?;j6?<$A8+{zd=>?E z^l$|Xp3IQ-k74FHCSW_b+SD3<(A{Ej1@pNrZh_~nsfn*JH>K<&aqtahd*%ZY_Ujcb z1jo>Js4{u|lLwvJ!e}PayO)z1>1K_?zMk)f-vmO^B>`d5@$XeXzOPKewUr2<qe}69 z9i%!((0+6Gf41)V*WQVSE_rWkTIsDUlX4BG%`1`;qqPYcG&VDb2Xqto)5nPU_XMij zqQNe;wwsJLt7C3E>bbPiFrT5#J0RZOyTqDyFfyu`yTJqz5Un0-YwFU_ev=4C8&8rH zF}o|m>(EzqL~Z|8kkSO@_%b(|ovAF0ZY-}eKW+HPgKZbA#J`FgX<>3#WA{c1Y)?f7 zh12K4=3vMLq<E{Bym$hesU>i3dlG?XY`CZ(0~vCWw&jRjuJc|EeGEl`m-3GE1OTV2 zW93szs)U%=R+J2em|IE6C&juvp$d9?owK?808=#)30s8ns0Xt?t$;0Wb;?K4tgW7p z19tBUItD-7$x)t_$<UZNv*MN%n1?Hiuhk)n6cnYs;hF|_#Wj4UWO(yWebPCRc`jz@ zZE+StB5eY+qD^3OU@1WXBXXo0iDWi_zl7a?j;|S=Q!xRwLmwKJ1-5l0I~*FpDer3Z z-2fp-LE@DT44trguryq%-?0~<6!_;jbY7_Qkk(lR37;v@)H(><%g(Ye>d$_Bn@}6b zYQSaSx(!?*x6H}ag*<D?WYy^<^p_EtYfd<oM1hj8qBeB(^#zsp6SJpac1NiH;1BpM zvN?e~v#&%vIfV?~4A~DYNfsgqL&}-7*P1V(niN2-EMYnfICM_m3u(&NzJ(st3UX2D zs;j{w*ly7SA-UZ**sKu6+y&m8(u0o0O;D8b6nJiZBa_wSNx{Ko9U7X73(vsDk(4$g zuT`0n!Dk@8ax(E}Y#D9m8*e(efo>Sl8Ewt<My*<t@B0`udEO=^kp}XW1rEN3AxP(K z$6-P>Oa_J6sw{8Cco))*Z3C<32l$0`Y#r9$=WsryE)I)8o&6jVWhEEI59xn_$?}f| z=IP`YhP}Chp)R75mnJXOnvikKU=<hBPGqh2A_~pt88uS;d6;HLEjQhVNg)YMGg{8- zHP;;ckP;o=Dsvv<B}Y8&xS{}3dVnoDFVMQI?gdq062S!6_yk0!BEe4-;VBJNusHTb zo*6E5-ffDY96$d2inuTNgICH|F9SoW<$)Ud&9S(tA#VxK2uLLUbu|p0kt`1gT5&`N zCVQe9%||PhKdPm%FKzja2Nm>0-3QuEdBzEC$&StU<^=^`?(A+la&3-~DtOCraY-T1 zHRCg?=t$n=Bj_pVp%QGw<Vw{3ep|l(#`j}mSyB5tyz02nY35|isQQ~fM5M_9lv20u z#0ZoH*tq&PYW=bj@xgslRR(Q8tL)SrTO4UbJ^>x@t}n03o1Bed_EYTfBMJr&zKl4< zpjY%A#$WOq!XZbsAK39t5wQx#9!_(4bsitr$w;h%b}}yN@9Gg?Pj6<B^m=Hy@tSiY z6&sy!U`f<c3i2jkF-+)`veqDU2IKHbbG|M@x45x1XIXMptOx7=ST!o-r4H$ZDdoxv z2$nVN`JE7Jj`?p}=6!^fq$pHmyb`oO#Nt|6KRQHm^JGnMPV&A0V0=!C&-vi+ReZ+W zF`-}!-DwVT*_{uDYh9oJ63fu62;hkJ1G8!wHFhOQ5|ftY`7n(`giWXTRCNQu9zKmK z=?Z&GzLF-CS^bjch;4MSP@`~bOG>tEkn5bcZW#%r@`X6R3ujd3Q;7<hAAI*M$xw0a B*9ias literal 0 HcmV?d00001 diff --git a/static/images/docs/products/databases/postgresql/dark/settings-high-availability.avif b/static/images/docs/products/databases/postgresql/dark/settings-high-availability.avif new file mode 100644 index 0000000000000000000000000000000000000000..4fd9cd601cbf40fc7b063222b392da501994785a GIT binary patch literal 42591 zcmXu}Q<N|~(=?2ZZQC}lv2EM7ZQHhO+qP}n_RN1j@7`Z!rK_q}ucUL<2LS*8z%h09 zus3kEFa`JzHWsFg|I;=W2LJP`HYUyn|I7aeLUUtl$N!%M0I;_(a{hn%|1q4sg|p57 z8NmM{k%hIL(f^z<KLFr=>wozC|1&^|$$yU6!ov3dF8#kO>VL)r=zmrJ)f%`mF#b=f zTG%_<|HteW_C|L9F^qvLqfh|p|COOwINAU2nEwF!-v(OvFCf@kxLf=$0}KHH@gJdC z*xUTS{{L$NH~<J30HDOi#@N6a2>=R;!_w@hU=RokmVjw#5=cyd1^|H{L>|DH_ydNu zR-vTd`Bi9SSEPizk%$}hIr}_RUA{>86{ojWZldtttkbw#c6R>i=CF%lxJy^d2$JMA zFlIef&DSWNVArlgbhpgx!iPGX{FKVVdG$8tHBP1qigIvW9!!mU^7|OrbtUc&%&cDM zvUX18M=wD{69Ea5;TP%qHxbYM=p?;x&2g)l*gx<e1Y(5C0&^m_!FWQ>&nK}>5fJ+{ zQD+5BVIPARQpk-Wq>@@dN&SKYNks0Kw{$$E=>$;>G)LjW4%aA7lXAp!@rrd6v3KSy zVo=BEf43mf7S88~Q;Bp{QJt~Qv)1Z-kr%iNa~zY|oW|J)AnS;GO_Ol1-dAudLp8qw zIC(qf<IdU$Rg82@P(!)ek1-t~T%?%XYTQr1mQ-O%7ZQ@ERt)z=XY_hKgi!7>JONbR z$el1(LW)QyBxVcBDLl4N62jsMxkrAj{ul^o=b#l}e8KY~XRDZyhfJ3t(8Up4Lhs}f zmT|ao_AH9gB<5DEM*#9}e|kW$8I(<0%GCin*1hjA3@F+XXAnM8PJ8ua{S1UNQ4Rqn zQ_MX%B_5@Z^O#QQ_yi_%pEj3mS3$9=Dv81OWx73OpkdV7D?Fy<7}7k#mSN;KKt+WP z;E6NaCTu0qdq}j~7h%6m^t~qp*QO7A07;*3hBX$d#%<36lNfU=EJVYbmh(Fs(h8VB zM<W$sFi88TT(Fo`-!6XZT*5B4TBkmY2j@)WG~3g@!lHGhBA1n4G37#XUiHK%=g|8S zb;0wH6#4rpPE(Z!%&>Of$GkoFNTmfbZxbrkzmZ1->$A{(B79aX(p=<kXvKP;xyYc= zEO`&C1S1pEy$p4p<@ObVtr|l+SnoyTX8caPgy}nV1tmHZyJ;%{Z`SXk29F3CKc7G^ zSsE5*y5BFKDn@g!(gt=;;3BYnOTYnT_%~JNiQ(265R+Y0H`QF1PsWdy`C}+)L^Jv7 z`($A(OH_G)+=`75H`12|-TY0{lEzLca1D84J)ggoYNHZL?jiR%+F>z`a=YxK!Fl37 zLA9(*6KhLbT}p7v@Z@@dTb}Fy*=qOG(k<B#Gp-`~i*`Buip*~5y2is`TaS(8IY-rD z3hyrN>@L^F+2LHw28#jz$VWuEn0wuO6HnrGxz(0!245trpU}^U*9o%>hvU+|nEC!} z#OUJl0d28`DHL*6Xnv9?YJcN@0BLGjgc;}Y#C6=r-}#$>ja`(JGHnQ?o@G}rViF?H z%SZhJBH(T(HTa3!RUTg;FNr&0tn-MfMph-EKkrlt^O;SjNS$vLUPdOhW2v5Fxj=ws z<Xd2O1PGjh$-vJ}&n~7Zo00DMPorgm=Ct}})AG!nchaOmli&HXqUuCs*V)|Oj~<k$ zb^$}X69F!V(#x^Okir^?rh{Z6IaUz6y5+uZh04>yKrzrSkOz|X+!)&UL)s!6-MTRk ze%aqo(@Eq&G2Brq3cLp%y5UK==0JX$G9+G|5@LhCxDN+^xv_QjRsH`k^9SjeRRmgl z?1a-XYe~JscgB9NUBFXgJ&mQg=EPEt`~r_A6NfCfrlW6O`-4D~tYj#O6yfhSV?qxt z=@#XN&jUfvp}dV2X^>Q;^)zQ!(~k2asBedZ&&s5v)~7fC?`wXf`En`{%G%tW?JhML zf(2>CS-gJUTuCm*>Lv)AujhgeVg;}bgG?XkpQ|ZdP<E67{k&lIMp-fRxE5na#;5?3 zmZ_Q0DWrWe%2%E>_Q>&IWlpvSV<Zc=^&D5qiq>PH_4W+Cg`74Lz2b31)E7kv4-(YY zA3d5@QgqtKHSu#h;1G`!XUU!P$`cz&#QF9#lD*8?4e&W5e=(@+0&Q{6P8r{NWlw&R zw~R>EBo#poD|wlb%10<ZBYwp|TLIqxiPoc}K|tkOWX~rkMqTp}*7E-;+`Sh^=qsUv zkcyv=<1~}~%&iZ*87x~Hg%7+dlOiPJ9*<(#!S-X0%<7ff6{ScsxpXKMBb_$c@>el- zf2!NVx|k`%y--MHouE-UA}q$n&r2LgXYZX-%dChW85f?(7AC3_%5(*!ekW|kTFL{} zh^ir{qZ^sDqW2U-Lhohl7zjd<x$);DWx+f6vfyIQoymRV&Q=U16R_Q^2bnk}&@q-j zY~}!JVxDB1@p?p{3+QpM|0S^Ff@x~Le-!vl=P?93e?r`svThmFlB!{(eeYBh?~rDI zQCxDO!VO5O{Ah3}R@zP{Av9jGrXedg!xnXHb1O*_qL&9vrpM7i7^oX6D>F3G$dWav zwK>F^=8G$zB6#2{a2?pdOLGA6v(Ay=X9~col(zu)+m-~-u}Xae{VU+^W;X5D+^|ug zc!yZp1=AtVxeCodWy;xKzOeeb7--2QH5uu%4%yzzUBJvspp>rXn})$(?Pw)8hZwI$ z-0M-32fiSXFBYRLU%%P8bwC@#GHyCWL%GEt+ZlowOm2cGMvCYAoOloB`laz0dT$7P zc#uEKSQPo1d+;tE)#n_~vj(Rb3zVb6BV43?X^@et*~Y8M2&|#@qVa2z<IpWAOy{U; zi6>ahz!FWOTo)K2jY!^^cANzbXZ?)eAhWm=3xehTdoSUO8}|gUdcHCJv(i~;7crE2 z4p#oA#u`i}uH)|SF&$*fwNt*>w7Xw}0ia3n)B4&Ur}5J=gR3n;q6Fpakzl-1z-V+5 zG&cUFWF$hC{a~CEZA?XGkN}L%0~3;+EPEy3=8ZAEthV7<8vCT-0Mt!W^bwQWw*Oky zVqZ`p)=)l+mDa>BnVe%b?pj?S1uxZHx25l;{JdjTc#79%L!Zb52jm$QJr}6%-@6cz ze-ud0yt0tF2su&f`dd453*iV0h7GH%#zxeBXm!J7L~}jeKw#~Zfz&?*9uY7*i^>bG zzdeyIjMiHuVAkK5Ur+;Z=lPY77d0}m0j#N376;akhpi)P`iW+qiNkGubRiEzS3$8u zpcn64&eFQH-bKtv&N2xRaCS{uuHT7)?^ZFA&RWi~^6}Gh<O&3$ntTs2&^*+^okBZt zjJNhtm3-eijHFFU#R0K}<x;R#2l_?vdufI^Ry_X~kx669p8s8Jw*=RA94y}Lop?oI zw;u^3j5NY7h@8>&H4*a~gDmnKcO5*Nsk`*XC|g7LDj%l8VC3|tqjO+GW?#6MuG)7m z=X39UWot#(8s|XT7Z5=pG|~m1fh}`?6M%yb+>hU{9s+4c^b@3iQh>=J-bS=laSaka zS*2uBC#)fdHT5R<U^kws@3X1I&{+VS@<hzLw2E-Jk@;|XJeja*K9^}N6b!Ki4&-Eg zd41a<f3NszR)W^+#jtTHO05HAFPh28)v%}@@ltu)nzIjz(`1*YNt;8~kITdiK#&Lj zV-Wby41awJm#AP4Udh#rn0cFc$%nd*vRvEV?`1kxZ{95v`d`UxAE_%0gbiK%dZ{Ug zA4#UlX%c99XGWO;0}|aR9Vws`nuiQhFP3G4HBfzD);iWrc`;bP9XsyniTsSjsD`W= zKHpso-`Zb2xi@lQ^~X_H9CuxFBK!#9{&H1dw|0|OKJ;{eU6gj{XAj*MQVZ7DwJ|2C zUn|<SXDso3$h3TQBS*2k{J#ow`AwZIq{)X9jln)TGJjO`F|3KfFq|_1cd_@@wg7qT zWQ_i2-%~c6#!V@^K7mQ|6>0w_)cwqk8_;JX4<wavq7YF6n@m;QmUiFP_5f=qvslq} znrVv@nfotz<bbOD(!nGs^m9jlTE1}Xf>eaoF`3qH%AnfBz*k#!{(<ZoLq{xE<+y~R zTlsMI)u>RXgG=1w*_3mIE~q9)IJyd+Le8_E29?Olz^4`N+j;cDp1pFNDz_*(7E7lV zGtc^BsYE%Q3uqNETUS-{oIdSe&^l+lhE~>D3Aw(gN67hxwu7egKMaTutry4E{!>xL z$FRRVM$dpo&<{Syeyyf~%VzRAH|1m!=)coSf;auZ4A01_$<w1P$w@}}R8YxcPcb<1 zDQ>c)wIROf^i*4AU)ZM6DkbWO#n-dnC`gMvc_%N|Q)8Bxfm7;CaZOKXvd%mV0et>s z%E5_#qpTj~Jlq^MdFYIB<Fw7}zz8pti+^%>vQQv{1|DVTSUl?ymtl;J$#CuY|9Uib zlqIWtJU}>c_{;2Q`_(bS(K{BO3MwI)MY?4y4Fh%|QnZ$O^zZ;`(E&47<#&DYarl{- zO0|WekRbM=@Mv@5L9(t#$*}#V?vetr2RnU}$dF4Z))6c#>LWQ6L!Te@PT!G@J2}P8 z4Ae|!1(7!bo`=@&jP5WOI{JNa>Je_aJDn<vVojl54YGKV6Yll5@<b$<o*1X~?ezAv zKe9lg0>BEQfqau4#Q=@xkW%xW@mvJ8L9;djz?)1f98>?a!H?!xfGw5kM<+fcg(Q#s z>&Gc??|i|gIPW2lw4uXp<#=z6HR_f6am_x(UXZ2syRN~GKt&}hlgCYt(#e?qfcgPq z=yZGJS>dhR-oJqE&hb)rWv!I+#-W{^`VxV|8(1Nxd9XXZmb3l7nhHQ|ETcog8}tmy zkU`%r0U9BnW(kx<hJtl9mAZY(`-N3S$m?#Dn^Hcik>uj;9b)$=qKCYvrW)^*v&>f# z99RK%^w<v#-Z=)YWaN0S)KGxBnm>WMJ-91sP@0Cq7myDIY?=C>z8j52TiLKI=zg4A zpo{UA_3@{PM;@O)tcA;@%=v)u@ROckpp0Vme+=JH2Ew9wuyd|w-~!vccz0HJ*8;G@ zpOze6j25^$(0Dhl7AqF*g%Szvril?DvYUaH&8Tq7P9XN)e(>#x#CV2u<Bdv3XE^V4 ztJJswrBh173gmZKJulJ$q)+A*_Cjh}4;2@He_JIMjyh?{%n<+~<x__dclkk@<uSVn zXtHJwx7XwxAC6nWd#sueWyX<XPIfOV1VK^t>MVCNNO(_TB=Kf8B6QgPJt22jfxw0F zdnw9hyO92%T`Tw|T$FjUTn|Zz`Q-4DotVGJp%3Y#yt?1Kj=tK5@o3~;%!TT{Q31sq z*+8qeb+GvT$@lKDJ0z<n+!v968}J&`KB<cXK_wviJ>#`+_1E?~VuXO|R|htZYoxHZ zmnRjctb9QqMR=b&e22=vwkjWHCM;JETewPtd&jQp&cd8XU-N=-i6YO7_HXRPnw(_m zHCxPBAm?8#)<5bxId>LENRB3`vg3P8_BsQ9S(?h+m?=ModPv!npx4syHps(HTOpCk zu*z%cQ8sr&y70DO@e++sc+3^}9%xaX6W8UH=I-M)yYN=L@g+Q$6>ACLwH>}WQ9ksW zk}~t=0u6h=sEh*LKRd%`nR!MqKO6&m^QdAN@MYG2|Gr+l6uS``kyXoi^+#|&**J45 zv<bteW&+9{3*A~5-Y%I`k3F@t?!sY;*i#T~Z&rwx!zo2TeymGTfjWHBocP6Rz#XW@ z97BWOBvB@ttV@@PhdO!SLJN>Iz1S7AAEv(RXm8s3O|q}frawKvppp!=ENDkat~AN# z6E<qyZL&*}#PpEM1CHQjfo~F`;9Kp83T>YBg)6j=WWK5~l}d%F_NV!Dol4tk80Z&j zq0W%j6d|@3-`dNWv^zGl@;e4|#<8imD>Gk1dE+ZbN$rDPxRCReceo^bY-QE-1~?Sp zZgK{fAO8MZm(wkkJFh5b9PC!-K3k~cihe8`o)gHvRP_Bq%btbKs!v&o>t^?%M3vn5 zE2ZZ8agFJlp<bp!Eed|x(v&$ju$?opX=m)tDYjPIb);o8O|j6U>KBRP?FMxXJCeTD zKNy*j(1Lc_uBJ>K7BG(eL=<2Sn(S*2p>QLz2KCL_U8iuc5jCqK%w=bXPbTEFIJrix zi4L4cD2tMKOt1Nw0zKJL(mMT1{Vphi#2u)iG5*$ucnP-~iiAw~3uCF9VM}MS6Rbd; zbe=5Q&0$t$NFy!YLivJ_wA}IwIgFVAWdEcU^bd1Una0Wiq$GJ!A^4i1O>t8#GuQOG zd}bTho&t{%I#`pc!jg-@RspW0>qZf`RW@o0po!Hfh`{(0)R};Qn1UM}_kOH=Na1wx zd{AqzRS9a3r{W{i^ZzVD0a|d%G0*Bo4ISyXXjQ&n?od7dw8ubxToMoaMj$6P3ht2H z<LRG7Q~@9Qp*)Url0?&#;w5qIUxXL4M!AXrhB+I%Ky+VhMDW>cU^_IY(Z#TUE#_;~ zw*Daw9l9^4VAYmcnXm`*Wxw@)9nhQh0AL}GycRsBVX3@xjR=vu!-60=7Qe7(0fgo0 zG0;KYJPQvnVHC<NkafAXq=<FnB>D+m!Z-jGclc}FuUAewHKm0zJn5o1K3pDLwGL^X z2sxckY5)%rn5q4_3X;L3<Y{z6lMuz{`($3h;IHlmhC9%9sSbjsT9jA$$y4Yc$m(d; z^hRt~AMm2t05<U7eDOxxJ<V`IT#Kb>RD(nv^?}P+%t#ZS!~s=x$}Vh<^2HkZrD=YV zJs66pJ~BR5J5m|k_KZFm;mecC!h&8I>q!Pdo*=y1S%6qAZyRgH1WR_ZA;_+0<k3rR zAXn^;Gj!SJfivO<mwpgULl(PBlAp0z<hE&>R8ZZY$E_GAH~owM9X%GvN6Cj~RIgDE z%P=$7@OLsk&F3HZ+1v^bL$AN8;gmwF63Be)B#HRrPR}7xKIJCf$G$ep(ZZSdI!mX0 zp@)eirlGb`u}BHq2?y(IS0A%oviNoEO%L;c408bHgcmYHnbfSv$KjCy_!Ov61g0@! zm*}HL+9;-@ba2LjgFyUrW?{`iD$>C{_C~u|^>1*vrlaU_&Rp)Hjf2#VSMpEpV7a=g z(i*2;)kXV)IL8{7giF5YOt<J2o=?s@!WA5Q|K~a!{<4~y^_LS_q7Zo{SF!QV3BB$X zRHeH=zy30c{v<CpvyEyS9#`g-cytQ@e~tnm!VM=_J`ZZY1*mL#?=MgFV}%GqF9fiu z0)&5E=6OKKmf%B$4*B2wYnY_%aVgqAK~hj~t27ILHOwU=O#Rv35?5xyC9UJ+e{al5 z)tf^uQ#-{+CwoubCW;2(ba<DU_o@yU5i(*l@f*{dm!{uCpFH-$aT9JJa}+F5>IXBb zxB1r1u#?4+jPq7<A<K!&Ea9-Y(IMxH#o>PZJgDH-igm20q>f_Cm53vO&N1|;c1hnx zpS$WfbWAB&cHY;RY^#gR9Mat4-wtTVpt^u`JSl}`ZU?)>WX_OW=3}3>;bp^I<!m@q z1of9-X(R1{3Dh?l{F8{@>S;=dR9u#$eAtW5X){)}zqTNtwu!^=wb0GQOkY6vl8w^L z-+PA_)TdFvD*4GFK+h9iN9DD9v6(w{9r1yCIiXYPnOO8AL!l%>RkAzZuSflYHgK{n zWTz^aW+S^lcwIwLDPn<XZp-Z@J4yFt_?W<->zZz7l(#<i_Z{uG!e8zwli!qfNRZcw zvUf~PyKmb~DaF?jsX?wxBowL!W9?<;7M?P#iZY$feri$zJ+34G?Lg5WQmwKF1j0d@ z7&<^7q39e;gI_SCc??vM2G=7pg&Tr847u^QnqCj;M1K~xOM7uMdLh8&&j&}wd+*Kz zu|sDSFh|VZS_$*Wi6w~}Jt^iQql6^LPGzp#tKeW2`DySEUNOaQ4dIRdI82?~d1mm= zeq$X;8Oy$lFCjhgdSU;|>2;$`DQ~M?5>T=QP!*D}ucw=(PUkyE?Bg^_ej(P*hc-9? zH{Gf!zxAL;YhR98I6SerzxcWwB|6|c-uhKEz8FRbWrF*!5~ANHCNY;m3D|mmoQ<ws z)ZGza+`9zP@fP|Lmg_aT+ogIF3fs7$XtX6ln$J%iU>4fH4JJdJ&;2_9C%LzIc|KdE zrMo$SJ`|!YpQ>6;*?9m(bEPT_7l<r>tfhS-wMb4{Qa#z<{(zu{-zr2(P0st(h9qxw zVc;0UH)v<4->FQvBq+o{d*!NF`6QTFWfD)~!Lf`iwrJQjGtuON8ylY^K>3cI!*$zu z)2quOiNKnpgBJ=F^J}Bv>a`hrtWQq2a4}Q7GkN7Ao&kjEc%^atXs<{t5g0i{5x>09 zF99S!vCN!PRKW|kne%kUZXF^yr*H{;5lZj=&!mLcJUPgL%7EN8!-WD;EZqkd)uCsA zZAAZ0y+c8XP&q{0XhrQr8Gbh+ngU4qu^IZu$puyq!w5o5Dr3-y&AtEtMLPsLc49+K zH|7>>nhd_~LB2E<fhfQ3OEXuEyuOn$&#PrINE@TZgAO^S@EA{LRTusXZ4`4(1~fkc zI|NHY0L|4xE}#1uN3VSW{jkzL35e8A8e0{PVY5V={(IA&?TBnmk=OIbgPDE0lDl+8 z73gYRoMyfU{|W}A3;gL^-%MgpLA@FfBpCi~yZC}R1fa5$6Ak>(j#dhpso1DSa+^k5 z+d#9|mJ?+lh}UBtOpv{^N_QRv?qBsev;B-Cr6e2!wD+ce%zJx%GnHAmv%}JL`s!3k zzWR({h>q4jXPr^bwzr7J`kKm>1z;9oF6ucodtKy~qZJ31^zh0<*>;9ZU3*y3)*bhX zM;$n_&P4WEks=O$CF-jr1Q_Xv*ZogD?ulaR>S&e2CFz-;Y@-=&RRvDUiErpDeg+*_ zSgBSBls6W62`@+iHSi6A%$v)P#eK{H1a$@Q_Nojy&Hy``xcmgKb;Pr0W5Bp-M%16u z^3E|fqHX#sl+ac*CBgSda{PzCOE7d?3i$@Wh?VH`iniVulXYSAa1~BK@t{vN`*j+M zIr@&%x~ljfK+QLp?TC<H(x>Z(6{l#5UPA5-L_VW8G~<7a*&ff~cL;_7`0cTplZeYS z;P?X@t%hJeYUfoQ;vIY_74Ubc$_%!}_Q?w#q}7Q=S8bdZ6gAW=S#XDX4x@2mdmFdi zq>@eydLg*!HFBP#wn&UUb+4P$bVzW4pJ{YSe)|Yc9&UmVl;$%t_qf>!kRLQbli7jo zR+XRwci_~%Ll}Mi8UIH2Ixo~@QqgQ{#lu3!KGcrJUMNcs#{i)BVla95^WO`8y5+}r z7hfed5QowYAXpuPzxcFCH#D^HL<)wDaorPX@XST{wnxc-kw$u(_)PHVy^J?oPYN_y z$xf$&c?!@&cQVpo60pA+z~36lEBs={Y8(Y=Y9~A{s)1Qi_jDcoO`W<BT9E+T9Dx84 zu@u0k=_TBD#0*w5$W=~Ul!mr9nD?5vPGVH_p4Iz~OXy~<9ML$-P&5AtE8DJw(^Q}U z%cZj>{pEFFzwL2x$=oEksGgNJf&xC$<Pi_`P>T5Ovl^Ay{&jI9%yGT-b8opwT7(9~ z0K1u_OX)jXk9CUD7I3%}8L6wl8J>RWZ2jmE;(Q~VT$69He_VGoF~m(*1G^-__JQ)P zTu4P1On=7Yezl7FELBULA%zb#9OYBOarmh5CRu?8si^y5;F{7o>_fQFAzt-HlTJhv z9Un&<yt~&KFY>)9`bVDAq;=^Otf-`qvcwh_&u%V=XFdBjfZjvg`%DbE`XMzFF#Yx{ z7AOZYWzT<II=4GI$??nBv78H)FTD$LM)(3dt`DeZ*XGT51^Y%lh7Eu1`|3d(8WFhY zl1_q0vSEn5qC;l6@O80}Cg_SgvP8u{Ui;YAWY#lO#Hw#3C1RP=**M0*_0MRCfNwYc zYY=%C^IU_c^}tOKJ@Z@&ZLQqxaC-w6RKc4pRMQOrneSLdh`ezt-(QJ;lFUMz&aEDe z*(|DbF+!AMmGh`Vtw;vzl8<uho27cDT8A|tlx&;4lq6=|_Tpb%`1R#tAi-&ejyZ@N zggV_<rr=IIBU}`w;|sT)$~P|f`Py}U5OU<t#LPfJA6;M{rn80M1-H8Q>a>OXq@fP9 zkL?5PE9Eam_-A<R4ha_o(AF;kzxMj<{0<w+9hVN@FMRwS33aDZNCBto7t%a0-A*WF za&teDu}j*@!UGw9E{(9z0kKYB;-hI~P!(jTYlJ2&$76onqN@+v(-orHIn_|h1h7$a zo_H|=^$!TSeB3L2no#U$Qx&_4y9pub*>cW|cj~}ec-b{vR^@n7*{ql6R<^JO{xYe0 zjC)WwS3@9SBJJeJH*#M^uxlTfKc$*Y#{@}B5`5ke2w=+NHdn-l&5u1JU}u{S?g?M* z7f)rkAGOi_3E%-n*|tL1%OKSR8ajZ7lo{zG5gGcYXMrOh|4$D0^`mE|XIq7~Tu)mU z!25l;<x|`y-x105LkG3sqQ5K)>BXl`JcYD;3WYawIFNfLE<b8)bMGL0Dx?4`%7kd4 zkcNCv;7VWjkPKXza0|yPDmxZcvdx<v{@Av?6|F)vb>nAJGvipqf|sttFjm3G0i4*{ z7{<RJ?7D5J?T}U`bN(?i(|uu0Oq$Wqi~Ct&;XzWr@MJ3WVgE}t<6zP8vVA%z)j{7Q zE!yhcG^nYGul`l~{2I~*flB7E^Gi19JsZ9quz@@W-tAFt0eKI`di7RL`?T!i;Gs^i z5)VTux9(@je}Q!UtA_Bm9P7)Sk5(5*4j6N;Pse+eL8WDVcb?&ts~0Z^*AN7#u;oZZ zrCE?$JJQt|aL)3}l^X}DQ-DPX6ddKBCb0m)>R!VgwC+m?(NKLvd2L#psXS*=Q3B<J z^2je@wYv_Fzq*Q!Y5(cTa@%qyR<YlJegLcNp6JB*q!#>!H?L-8pjzOf;!O!P8>^}4 zyFmjgTs6%$x~4M!1I*=M91qZ_qriv~sU_?q(e(n}>ol*_W>jL1fWG{*tLJI<ubX*_ z3JRk`Gs<wn8~(201!_S8_!=5vP)?ghz@)DeByjG*w(yYOtVk1qr>-)7<EA0-WB33l z`583X*K3JYI!du%i+Kc7as`m>I-)4q9Hk|sW6_R`s7RLuQ;r$$mDM3BN$A5r<cjA; ze85S3g1_4HEtmc_hW_}lgV9wl9vPCp^@VyH&=*-N)$$}=1Cz8BIW<{wSczaIdcI?r zFG5<Hx)Q$;F}r00iX+qZS4IRRwKW703SiS@JQBOymyATk0Ge5>%3_mLyza44>?bi9 zR*#U+T+kV%L&=A=Yk1-eM>YF;+}~#wMR#(46{|Lb0GjMhl2+-h>!=uKX`a;Fc^;#< z73bcO$*9pCb3i^pja5e7%A=o66D@XZ$TofFn{xF<cv|0zD=39ZR7)2mYCuqS*LAbO zWpenpk?aspjC7{MMk$)Y?zw4?fj{~?>=6L#6~4#m7mE69`bX@Y7R_hfT&mO*R`5!X zP1k=*YlQHOT9#ge3ilnL5BP=neFO8s)74uAt?xKLuAu|<zf50+6Zv^V$=Ii51*{hZ z{46*lMkp;1AXlv4O=2wpm$LewS=MQN==U{adhFv|mmu(Kr>w^DU3D8}s9f!nzGI|^ z<%C8~c>~8L@t8+t{NqU7x-#eCEBVm&G)Bwz4dY;l`moV4GPJ?lb<u{PO5-V#ulZDp z-p^R3TI=7XF@=A&P8g<}uC{N_42KOXLQ9Gz?Xyb^mUnWIRt@-5+t6CV<g=zSXHYEK zyu@V|FkD~wjQ%hCyZ)eA6HosL^Q(u2w9yd@{j~0gMXDRDFh4W9N7Thns`w0F{6{AZ zTA^W<l~Z<j_wy*glx0^?sk@O<JA1nw6_!H1$EC7$WkJF+>2%G3gr-vj8Lk!DU2lOJ zbVh5^=VQZNWh+(O78xHl9l|ZJG|)+Ecp(Lk)p#SgO>+1gIZ^@W?g0A2%q0Zud*ybc z=q-)kL`w!H4)rJN3Z36z#fJi5L8E7nezP>(kX*ESjH@(u>uU-FZ#LBjuBmX|ehxxl zJa=L&A;G^s%xn|ho$C!tmxZC;c6MX{)cFW(q(eq!$m(V2511K`u&`Q8oqY3O@<d)@ zL@xzKf(AD^g%{;;h;nX>s(O}K$W7GEg<Zf)4;*rL<)l}xu^0rcIh)I~<bHyL93fIf zI;hCC`3^Ba!BtgzC(2QNPtnbrryJtbN}TJWmU}B$Gu6W<r1_ImAq*?tBKpgy+)2*A zq6ED$dVa&~yqO9YmiO^Ka+u0$)U8L!wC#k_ISq0lN8(jx&~stbw2a*W<znY(x;Kx9 zsyDnJ5``t;Q_SIRssTDDej}3zgsVf12XOlg=reUU%2+Rvc*nda^);|4;9KodJwR6l zxl8r3mgxLUu>?KR|Adt?6<;;@>8`z#w$>0I9r3D3QEeEt(xaEkrG)Hrm3KOI+7UlO zS~+HOM&4vXKKI|@;wgh8vHJb}f$(^`Pu!=t$_b^$71<fwDBcu4WFhW6FNVAqatiYB zNrJkH&rP$bg}Mbv=wM1^Ke0Fq#YUNzE>|19v*9GIQf%2amE1$cjxI$`$$xn!57JV^ z^Gy>4wh4aOsG^nDq3{sE8M(%|QD<K6O5t!2+|~^~O%^tJUpKin;88TIvAbrnwkAyz zN9L$N=R3*se#-7=WIRJZG`(j+hYC~(e7{q+>j~0vE-N|(;TKt0U4BPt7P?L?yr;y5 z%rgthpW?z3W|$T{DdlYDv;BRC`cO<lKO^2=z}6{bZ@@7>5txtzrm0H<h-AJZXLRLi zL}BUyfTGB(P{vBD4OV8KAk`|6>sUqZb;o!T1g>L-mg>CWV1prEA@(TyW2w1?lv!}8 zE&VkCH3}9<O%lC^W;T?AQKjP8E5z_YUrTm|*h|J+;dGX~T=JSXO6HX;s#(#H=LMy0 zAbuj=p}dR8o!P94&r$+QuRFH6k}+(Rt582(fux*yL-TM_mI<lbGz{{BnoMyP7(R`J zUO5$irwL7cA32@u>zFu6PL{4;XR85Pv}JH^M6aPQk|X}6ZQTCCF4I}OdBw4xcV<sL z6xbRIN}E&X1S-EGp-_CbB$d2u2)Ud&1Ei?ZkFH_Bx~#^%L-zk0)+s0m&R32p@U$;r zhMk#ZpP13|T6H<$Xxv+#_t)#8Srpp^Oi<dwsb+sEbb8l$zKoXw>M7;?*^zpp%gk!7 zY}gDq6)idR5`0=F!^j0x2xA(@e7L%M@M`8O?#4hy)<NhJJ>Ncj0g>-QU@*Jt(t5To znz(8>f0o{VKEAe@U?JuI_Ff@}`k$~^Y825!+rCqr`70RlapC|9a!Lpg13LL(kY4A! zfl0eZkRkgn7x1vc#zGJZp~(@^Dj(1VWg7hwII9smFwwoaaR~1XOojZuTKO?HvMoMw z1%K-UY|CN!v7PgwbrOivQA_CsJ+3ms6A9`Z;?zFw1j+6H1o75;UxB^c@fF7Dg@mWm z2ce4<zQbtumwJOME9&>Ltr1VfuQ;YZ>%Kgx&T51fkV-M}>I2#jJq*Fw-TO#mQCby? zc$!F$ne;}RJU}H0q><)BGQ2-jtr9LQ-Qy&2XZFYp^NcmpN#vQ**&<6x9#e>vVXa!~ zkLKRMk^V^91pfgoN9-G+!~pd8J6?cuOqz0wwb=CDBk0XYeiY8%rCxPFPQqJakSAMN z0JUuTzPQV{{jjjMXIf%mxxkk%q-Ip97;Q~a2A!W%Qd-39nc};`^98itnPm-gdn20N zaSIF|hkfp&_Yc+_KLC=a3D%heOKtHdYY7Imc{r1?5hnm?tQ(z?ShPi~Kokd3$F2>i z5)Y?LgHygv(S)PxQKK8(sde+sNIB=X;;seRgL&5cO+j_PU07m~cMkjcUtD?>(7Ewk zbE3&1<oR=rosa>!Mc5fTuX9Gu`!59mubB+F#Lip5jU*P`MKau@66_hL@7ntQz@J-v z>+L)hoZ996GNqC@#k7+~-sCyFor=%|FN)=}{}9bOWH4^pL2opS!R`^vKNvT(w{zbI zUS(9|v3E(M9|*41URR_Rf=+LIZowDSgZLzN5`fDBY3Sh1@m=I#^L6W0J^u{vs=az- zq68Lne~g5m*EZo0yjCjpSfVcXb|r&DSnhm@5YbQ;Usy!y@yk$~4ZX<MwcFE!KGW)k zvlxDkSmMJZ%8)V`yWy?)(NjH^)YPJ{Nui@qH{YSy?$pGrc%owR4c*0pz?65CUF7Of zFA7~VQO7u*|NfN;a}YmR;k~JsTlL{TumE-6DDsMX65PWqm;E)jz2xay+?-fsW#xTt z9#D{{trO$zdELs)HnZX=ydoGw9xo=^J_{1I9TN847K&>YB%|F|ALmT7OCbRyN#{HS zkHU&*PUvf|7b$53Fs%OLnO+5HFUOOAjY~PIM&OWyf%XA&d+<@PPGubZ<T#Nq->=8h za2%BXiJ!`h&9AagO|hGyG<=z>Ep2m4k19%qxP4gGJOyT*Y?CdAR9I5@XcQYcO&8*Q z#1Lw6Dc4Mx7qQ8u2}9I_I6{vM2!)uyHc;~h&Xbo8{2Gt2pu0(yXupxsI-E{hZL`Pu zar|4AT_nsFwOl98U079>-bbt}?RMSNv}-A#ub4qY+l|+RAWT$DIB=`*wTXZq44w92 z(f?{%KXIRkzh%*qx-14Fj!{<9a_S(o81wXTJUR-=s++7D>w7Z;&g&jkRf<^u*iEHJ z)jRIfpy(}rC?r*KP6>t9kJebTEAMP?<7@XTg)60!y@<iua_ggJn|nSM-Smy(-{H_b zbgSmV`f3^_(8|l@2f6^(3G?~^EfQQ86et3|-K?YjKFeTMJ1<@Nu>qG=sO+-^jS$S5 znv=TB(p8k4DN;ahwt7W?U^WED=$u$WfiEcy-~&;P{h)C;(?cS83}+?ZTe@iDWl~@` z`E~TmxnW~1U2e#YVb%<`#UW8tEUAD;Pb2>e3WgsgVG!$-9@4;&2GcsrR1S^heg;7y zsJJB`VIKvy>i<`=bI-!E>f;d~jZw|lK{86k>LN2*YUKBGS5x*D-f7v_;yyN59Kr$d z4G?wGr)-Gj1bI?;11{|wa-{H!_C(WQSP~x_&vzN|yCz)itIX3Nmk&Zwi(#oMstT() zM%LrfM*Mg!Iy?}r3v=Teeo>Iu&6OO_6ZVC+<!gp!_3zU?FIB3L3{IkDwEeq0W>r{4 zT--7$2HKn-00jAJX|v8**EAFhbI|#mnADpY(K{$i%h=e;(D%;_`M2(q)VJ+Kdu;9* z`_1VB6~xHb66=f<FQiOwf4=i30hT~$W?k`4Bt~^_4wlbusG6EmJ7?=-+q1WFW2kLU zRL&(a2SOd5(A(;{G+1L38dIWNcD;wRx;sbmH(YV#M42}-RNPf5Vzo~33x^w?Ip#Z5 z=|hm*)OjQ4#@p%&up-);gA*g)M3sc$c@Gln^zbi;)%cFE6EnHaMfVlp3y@3YwAeBy z=C4*?WyYIfc0Xp;h#Q_gpx@LOctFW=6%{7Fww?m51aNG%gM%ygTvMiK)3bywr-7Ex zHE_CVjcR~*aYH#8XzGBZG3WD_&oW3A=ivJQ`J}8+-N?i%{Wn#^;tM=-Fns@fXn@JQ z7Alc|Hw`;)vB5)y7x34OzLGML31w*AKF&SaLt|;+cY|*En>ohkk}7@ei=gD+xQ7RU zfFl<J4vZx6IBpd_5;4Skj`c$TxD<3jZ>E^t$W-xj-K3iUDsg69E2eWN%tF4I{_*N& z(Cf)loShk+*hEc}zfZtphUAvE60pg*(W3Q^6l&&7D1ZwxuKKtkpEWtHIz@~s17GmF zM1}Xg$$e7~s)Jn<PV3rTGiHC(3<3a8XhxWpXppY81vdnMthy?CP0u(-Y7e6|IH`0u zZ@*z(g(vbeudEO_Ni_fMFrRg>V(d1EHCH>GBC)ew<U-Uw$^Ladr=$?f!hG%TxW<H9 zv{H!$c7v4x1}i`r!Efb!M$)^9I{K7nBuW0xNH&UQqTai)_cB=$(!N_)ZR=}OH7%z3 zCH!p;P1vemfMLN;&3t}SbKNN&A-^7KB>e$C;nb^BriMchVb<hVuy|%-)aQz8jAYFU z*t-!3bX52OdD_hgiEzxEs>|;wH`2xG<d;HME>A6J$rHxhKDVSo+|tl>OECBDJXdWV z)4UM19J9=OpuT`kP~{w69T2@VSJ72(5)Vx;U~@n5KIV3#Bq(AuuJ?Dx*SN!BpzP&m z&j`;{4#e_7_E=En;u-NSFpl3sPA2zSb2JcaebUdnB>+Q<qJTOoFrT)_k|+8|jR}DT zqYlHAVc9r?`9DUMT91wo7sAl&?p4J`=><`4F96JNm`6>%FyW3*#vdv4ZGduel70hm zDv~#y#5xCjZWxGP1CAL#MG8?i1AwnHso)nEX--h%`tDxD*C00e6Je`!A$dp={rKQF z&G67`-yLyWg1|bz-va?zaz!S>gW=Nm+rn&HB@m>TJ-{cK>L*D+7S4U<Y7Vv2yBMAT zg^>cxY1&XCdlR4-OL?qVX7MUd%%GPxi%$SBdBN}}Jo&ZCLhmMq;fAf=xblF_2?$PJ zEhLt+b1M;Dpu>7GYjBbuI#U0e5$!$SDohLGOfDl?;lrKJp|#<CThe|ItU!#^wbncM z4HSEEn;P5BfT;nw4<siM_r|W!L8gm)P4Ogrdpyl;F3vJ-y~>e9+o8CvcXf$C*BN+2 zy*Y@v^qDpJKL-Mj*q|6fe%Y8qF?$I6oPQ*s$1YfY(Jty6d*c#fbVFX5Y|JS4^DKn< zKlp`@^eE)am}f;@JlZ)zj_HM3{s|vTYgq(JN7FNzWHmrQ?7~vqOF;hW`<8(Iwl1x3 zkDZ7lE2sKqMcv?_Lh(x%vK+;qT<+})&X-%LH+bE&*LhOqYI||uGjq%<+iT+F)S&6h zCdezZRMGt%tkkJ<d()-^RI2%7C*S^=z)?sjtCyn92wGwm?dm0~cN(IahuHOZj@BKM z7KJ9)D~XMRY^c+KW1D(vvB1O)$>r8@8HF((M>yGUqu6-Rk{(RuxJCQXM}*A3tWdEC znCGjS(f!|Jl|WsVlngxn|0*8pFNws0d=ui>Sm9gRkjRy6k7T_5ko0c#((_87J^o^` zDGJ>0@XDa01%w)9kxm>OqI8?CDUJ2^geun}4N<7eBuK(9zufm!13k)7NE|)*#-Cg8 zSl`A|>F~LNw+d^?06>{o6kXhqr!snap{GSLAh(}q@^~@x(vFRbyL@?s<*JeM514NU zFes_d$JC>(#hh)!1V(?f<S8zG$fq_Fj#Oi<@W)n%$EmCaeuqf`NW4dVbiz~J2?98x z(q#J#mF5t7xqZJQ-PC-NCi)naLSB*|4wrxRr%$^vX5lsvT2VwQ710%e=<oFT#v}GW zvO~gaT~lKxS-U}YyZWx<v@SvxYgVp+8De~=b2<o2WozIhFMK|qHSCwO3m5&R+99IK z=zl#zMAK~x*zgBgOngqGWDDCdm5ngwRKJYCNIYP;!EKM<^Gtnm(Y}Bp!9#Yp-|KO$ zLKU@>$EzS%CW?T1vK(@WK2PW+I`azIjb9(Jv5@>K-{?Kt0Ymi@KlWulWeuH*X&m3? z1_hUTBgga(<dzf9@8V$6rr(k(VwDf3HSdwD<r+OA55X%~<j~k^&-A|;HtJ<=ofR47 z8~Ka?5I{x`1W!{}VD@&1{yKh`X9bEQQgt8c+jLM>6LhWBrTckdJYL@WPWA-7((41o z^P!xW){pP6`)cZ@9^s7!Zpub8eYA_AVG`l?3}-QNyWn5Ucv#{ap^QwYs3j=?H6Vzc zm=x4<^}qK3&PtwP-j|rGNb@l~zO8)V=0+&h4N`<IwRpUH9Z<3S5&24Ul5v{3=?1%T zGr2O^KWW-OORRK*_=Tq{A~LimU;Bnv2OD{S-Zc;sL%B#3|9}EwL9$o~)UUM`EI^Sy zf2pBI)Z!%C;8WGQS)-2JfEI;G`p#AhIf@Z9cKH8|$C0UFn{ySOHr%LVwKZ=3=CbRl zW}@TR)7n4A@25C0<3R<SIp7vy<e4G)YKO0FWoj1^186C{nf0SU`j7T((m~EFWL2UE z)?UG!LSZQi{I!%K3e)DtxuQj}o+*qwQ7`9p9mz8?-f&GBisAcYufO~2x-;c&Ufjqy zW`Xmb!3nesWP~CL1U1Ac6y2*d;C<o6uU?}`V<c2tDKV<YHC|V3QclssGA~BTRPyt! znP?&35Ns`588~P1tAQ*WIiRbh?&0F(XSkh;c@`u#s!Sbqp_O`c9qdWzL9Rrx|DC~V zUOO4$=UfZhit|@6px~{l>&K0MYA}$?t0m!}1lV<#s9nvHD&nQB{A{Oc-|&b(b%13C z3P_(f6pwq;T>B3*NYBw`P%6+;>QPl?q)EUK&n(}Me66J*NS{KVBMp%dxA@2pU5}VL z1X5iOXUaoc-g9ipibIWv4_>4bGSeV`(IjZ5x~&aC(@5uf_wm>p^oX47ck(*K91W(Z zfTHhTh^;i!7%ToOzEiQRrR?}uAFp*-*`^_RJCf73^GiQdU_4&i;jj;&edE-Px+5@+ z&}T`Oi2dK6ZyFWZ7z<QYK91K2>2>T+<7clrG`lbg)kH;5__AUGejEv{>^Jv$zsK%O zO1?X(Ah5IRG~0ks{0`3g%UK#as;kq>hk~@pL<xMXAz2$qd)OR6*;w??{%~9fCWZHb z9!N!n3YNZF($Ok4Fy6SDO&uQqOqYjTa;ql=?lXN;V+_H0ZnFtu#%m)TVNt-M4p#@7 zW_b-XHz4?|!PahA53b$G!yd>_2{S*UUz%emS>sLOH#%i=+%qtg;1<PEr&3WV;M^3v zAW9iKaN=fSMiog2SPbBMFtH{Mt67)We8CoZKFGpfBS=Pnw?1>5X#*mD+Y2sw6Vy-_ z72&Jp+P+)w%u@OrL$}bkfWd!zbX+b@1JROXP3#L$c0l}Z%<x^XnCcmjy8f}1=6&ad zuc&=FzM38#5<p{)`+6tk4-w7F_{SXym$pP8`;S)s(*6mGEK(@SOy%Tu-q1tnz34Ei zYr06o*P?wz!C)fwC4dErxwVQ@FLjuU9=jkbsSHcnn3b+?ULH`+8K}i#4B8+=@_`gZ z)c~6A!z}%g9nFK10W~xw6N?8ceEOtSi~TRl_Xx)8ccsn&c-bgIT3%-sgQFGv>wic_ zvJ0XgSFCWov|$-L0_tQ@dVcrllrTUpK1a5ogHaMwgZAO$Db)m}gVOl`vH!3jMU!Ze zV)Y<0f_04W41#!*ntjZcnaGQL+Dr)D{-Lmq5ckgr-xDSUf#%ElXRVTxT#rtM&o56t z1#r?y9w~c>Z$1B@-jsYZGYzrEADFBY50_;{Y%t*3=&FP%Rl(nmlCVZo%gZmQRSIOn z#0sdL?$)Sx!$J~TM^qN!uYjVSv#diwu(wav+W(Tx&6s@sE;)<Ab+l3}y0bFgZUsS; zyC~{9Hpc9a?=P)KjtNUm_y2)yav%?S7PuU?52{e5Yeme?^9A6xvviq;eOl)#THuG* zUyw>Wm9X5+<xUY~xG4s-C7cO?r6g*4jaSX#+#HDn67Pdj1CT$*HEr%HvCTvsT3WG} zuNfzKKN?zR5gd=kDZp*w&bYtK=60ynBuKi}e$(EViz<|WpHZi{Hk!6_uf-9+R?ojm zM6VEym?k@ru=>+i12orbH$Ig(Z12R~4aVT~F~!ZzpptT~Lmc#VV(?ZKfOVYRS8||0 z97L!{ODYXmC+^<KeOi%ERNnBQlKEIVd9UpSs6GR`Ov3YP;R&?FrOq<fb@*sHq*;jM zpByKExe=AR)<WugE%A*<;ZpHqZGdJ)J0F>yz~Z^wYnI`OfW@vjQ?T9E6;+OB&3Q=w zW(ckL05yWy)G*2i*bxe&j*sI`g_V+JC_Lp9B~8F7lNVJAUr43l=D0PRT?AG+6xYBO zDRy-EgnT(QP}+EUM@H*B(p4{`I{~sy-|^zf)0z&O6eazXnsY)ILK7lU@iY*9Y-&#a z!#nHqjkq?yVH-1n2A_3Yn}UY*E#Ept@kPJ8+@jo^<A_Qxcl{#%&F7&y`?cR>NR`23 z<YM_|$Yh3Su;r_Uca|QXr|xsRyok;oQL!2!f7K6vV|eu2>f)W0uo3f=@BYMDBG<c# zwl~QKTrH#La7H?db}yV`LHjZiYi+AunhGTEp&YD}SNA?#DYtr0QpyQ|JnwuaVJ}B^ zgpc~FZ@Y<63Vk~m?3qlj<T*|sgW1A_ZfdTNnA-g}>B7h&PIq)Z8qPXEwHX8+$*`hO z3(r`<8gr;I%Fp{Ql$^reR#Z8rRH>LByoTEDyOlZfF3DgJtu+9=_Slu2O^@hcs*>_S zf0dv!qW02QVKKSP`<Wjv>GP;P2&lb6Of8G^N#sp?m!6ly3o5)=wY^A;LG(>oih?@1 zkZpva-}MBo$I?Eij873;i?q&AbkbpumbKs$XfcF?RhsDn5aBAl>+q@aL|8<lpn0|J z+QMo)MHtiCv*eL9bt`3x-=UF>O4=AYLE2%*-{pjaew(*x0g13$V6lT(uQfmcD?xPB zaJV;IN`tEpI*Z_yLQ`CFSqs-5n4B=lvA3w3!CcBbc^c|sQU=cM7Lk>%#n+73K3J-e zgOW=9TJwT!egZ}9LEq$BF50G96;NKu<>UVTMz5iw31py=-``cCw%(0FwmOR8gbZa$ z{=|~T!*HwbX9r{cw>Bk~)*FhvCwr~TUWe+9p}n~Uk3^_X>DOO&oD#H`n#8liBxAmv z1&HH1Nuj+tja6}J8n^H^lQI#4{``>#LO2=Q6`@e)^Oe=J^4}ACr>59@c$t-|dhHZd zm=@5L_dzDd5m(K$Af4FetGg29QFOi<5b^WrqSf)+!D=~o0I?niSb;NrZs}K6GE8@` zU-~w(F$H0$sFC+Egskycx+Q}O$B$Tt+{^;Sr`dTb--Q$L4qk}3IKicEyi&%wVJZ?{ z3*XF<WJl(Vg4mi3f<TI~R}#}3b-Kp(Uj(A@yfZOnX1fA(N0>#(nb(M1vzqin`264$ zaK^u_`NY4lBIh3A4iYxUANWoi4j)kPv}Dyp+eY%KG8hUEYw(c9S`Aq?9}6+ry2Y?l zVmI2a8P|&+QQp{5V|{R=u{8^erCh!cG-Mialw&@^Lt1Uqy&azHl5FvD@;@DcYP<!Z z-K1_1TKO2;#lgpXHG^$Rp*h=uNHzbQkI#ZS>Qxw@0)q}!eSNOoHK1&N)W<0hmF~pv zTIa|g=yUEdv0~eD*)6k|MCQFpUqZ3*$jGw(?uwrw8wnmFglM8uOo4>-_l3~xgp;yt zlLsDJYSn<oG?01%g5f{~3(nyL5y*V8&+5jb4Nj#0J}gH@KWarG{Ia1YOs*c~F6-N4 z($(<R805!K`K>VWa>aF2$-Fuj!f3`XugT0~FkBD?!0TPr65@WbZ8{5jJ(Jr|{mI!H zV^NjE<8|@$1KeXl7O5*{?M)T;Zrbknp;0Ta;K;kFO>~mBX-98b34!@|pm}j%yy6VM zX8c$dIrC34M(l#ygNNlxr(s~~UJ&!K+R9Z{Onh_`UNH2a`1np0p>O=2Bih>u(gY+o z({R>YuU5F-P|G-F5p&YUMZVI11@{iOH44*a$~ypUCzli)3F`@P`h=>Xs3*}@`7-A1 zWNNx)L3v++@pN$UNRBn=a^R|i(IONMR>QCdWB68FE~=t~5~<t#e7Rp>asEF5ML@d0 zLKHgPW+gnTXffG%o<BI5*n{1J+#tMC-?-B%(2Krq6QUPP2)_)dsR*d|a0_zY`dRBc zEY>kwih>r^VUKGCmLv0#jLCq2@o~Zjz}e&@5oP5UtY`J`XAE(YC+u=00`shnHOB$a zZwsyN&I>Fs7Z`JirOw0`V4GTgyeJ|x9<^~ayH7zXN<!#orB+n9KYEaDdZVgxvmeMT zZ8LV!U6R5XLj!!}G-f|zX{uy|1D+RWwgtk9k|Xo5dbZ7T1Tj4swzPN9?*|SPDTTHw zvW9uGm+-~wR6xcB->H4M7urbvWyt0epi=G!%Oqo2Nj)G^Ft|BB=-b~`rFOlU5(%LA zjD4jtE<333cI#b4p;|iv3^xs@5^PPanOMI~V$H1v^UOuxViaOVNY;n~MJ+=qJX&NM zTshY`yvZ3-qwR|88?>=yDSQx8YjGEP8wE?)NrYIqr2bm<gY_GQ>z{d%$1xry&vdf* zz61K+Ye^HN#WOA`@GyL{Rt3>W&oXcVsV0knr9L|sc7e>|Nz{{Z3son|1(6fa6+>N% zmkd8V7aO7;Z(77`Y%6Nj?<IBeO(l}=7b=}W302_{yF>hRa0z0>?&;MSRb2F(;cS&8 zcMPKD=$7#3VioHhCk67a*0QFCwtcv7L{BG!cTdFq=5gIFMEO|02feqa2O&JV_qce8 zbb1n#uKaGK&^3?tWRi4~5`wD<q>Ul>$<~dEPln;fHp3lU6T~&oUKn_{XYgFBOm!0} zBgYddm4Yjq+xH)TIWLp9zJ>PFssm%CPxWkWzDB~7Si++DcFSswK>zUZmt#N)6B=jY z;l{t7-0Tk%$q8w4rPNv_rz|fRrv_%H1x0tMN~q}j%IpqQ?4Tt+`)q(LoE5C*(Xv$d z|8fV3Epw)5vC0<3j{MB%0Y$a+Jl519@_iHa1YX52A?*D@%&g=O!)Odh5aYP_uNhTs zcyiPKo*f4&0Tb~g1o-RQ(`h!|08oGIYDpCQ9pr#!Qr@@#j$EK0q3Yxt|2hmR0bRp& zoxDfxu^qRRNe@)Jv1<IwW8jZE!1F8aa|tppnT+EZ4tRXW{9BfLDgy+3Tx%9)+UZ5K zwnAu1-F2D3li}G4A(&QRcmfeTOM!BcCV6^S3*56B+KSq~;-5z7s#YhE>+A~e!>A91 z+iRUDg?f_bJwm9TJ?v}C@!FeuJg9vtD$maAn<5e0Xqv!ZUPnJ$HHu#7tsUU)eHmMT z*ZWa+Z2nhqA~lL{4R(qkL2GQqErhi`1@RGjVd#^smpZ?G2IV2pxcFUEaci5?ZF`ie zwpo`X)9DP1Ma|WG*pb#nzl`_FgqLF}ZZ+;uAD6j|2+9fZ$Z#{^FdH}?`S9@ziT0kH zr^5ChYCNN&qYsx^y90ZS!l#@mR!x{gagwF)RR|!HfIVn-*tM0OcP+N+wYgzb>NGAL zpaKZN5Ca7`>IV5VYl0ltzGJt#Kg`!~{TqkHae^;Oy|ttf_iE9}yP0DlEbR_U1xpiM z@~sg^ARNl2Eul2D9MUw}k=<DW3h`59sd*Nlj+^zCe>Af;T!;^{BBEdhDDaVY#dYI^ z_}?79Zxueun2P`uFGJOveUsuPNu$SI`+$vhcgkhRxXb!VjIxtIumc~e5FSAv6}Ba# z0aHHtMH!@Bogss#M_KXs>=0yBJpST>(VB{jkx&DGWn~r+<?1ZyZa5_UCV;YD@&g&! zyiB(~`2H;wv~!PhAnYKxOg}?5o<&Gti%w!Tf8H`1JZSjtto|0Yk*DR!sr*_?_Hl6C zH}_6=EkN%e23E(($5^Q(djn?y%>GR2fi$+BXUBsq5SE&?G%v6^HnB^)RG0Zw^N&j< z1CVH!o&cRa<-JQP%tTJG@=9n1g6fv|G82Jl`o9B!ZhQ@BpSY)ns);PRZ=aQiH;Lhi z1n1rJ`xwG6WHA^SS<80SKx%kLOFAM|&S=0h5-l>W6<hglzQ{s|b%(b&qg>Syz}#7f zl)xG`Wii(a@S)-#i)NQ(VL)N%aj}T{W9xuG+^$}r)?WOxcX9)3@Ti&K0bmo#y@#~; zMg#w|$Y8nZO{JC$R7~u-=n3?^nAIN)^_w8N9Q~&H$$`aPz%F@*mXjXB28UlX6>}wA ze~s~Va%on#I)ivrw9~PHL2_d}NQN+G0f%OO`hH4;Ig*Y)+wD38M-KR5wJ3;R0`(Gz znXfq9J>mEwT8Zkhq{s+;fJ^s;-l11TeRCTgx9wSg9s15j8+6I<XBlwy@hvHgf0GB; zGV}DBbDqYb>MD>=6Rb8)WXiXz`Mj*W?#Dk!^f@)w{6S^)Hmi3e{BCj_3_+Lmwj+!1 z%lZlG)9F8IR8drOnE!gTQUQo1{-VpERciMBGipipt7aa^JJg~=EnBn*UI7V+gbNxM z3a>G3g3xb`;X&a56nb8vB(H$Lc!=?d*&HfXOyfwKWf@?f44ycwPxaKmvxkNG)$(^5 zI|yP&n4FMKwKyHqYFpl!##)FK?5`0{-R*8H-n7E(4JXHCt3{RLoxpAzg%dtSctjwk zQ7J*08d;S0oAPit?3FKmhet{4r>Q41T(QmLRlM2Z7o^S26>sy6AG23TvhEMfQC&<^ zHWz*ZIN=d$A37wiGi%6@nC#P=LBHOoVf4&ja;NcFi<PDM<DWbYHTeZCk|1CyGsHTy z;Se<`ADK9Uym2c<LEeO;T1W3aO)PO~%IQP568pToMEm>-Um~P%8Ss-;9(F(ygdrK$ zx&S?=m3&7f*6us_|D=0JpOgN<NX=ek=)~&r4Obh!-;D?<74*8UC;?EKi8G1Et)(nY z#HEp18cGNc1u3lhZ_e#-{dj}+Yrs@;2C8=cW-OP4yCot)BB=ktFiOkpk3OEURk~W& zTEr^-IGZ4QVJuA%1BDI!`(d_zM?CQ&Zr9Kl%1WIspw$!=hR+)Ha0$Gb5VpvBOi--& zB7|F9?O&~;=`6<WSVG!-&eCS?G*p%*wv^T<sxDB>Y+&V5K>A#Ov>k9Phnlvx2wU~S z1+WY+*;ZO%rfsS8UsItBT1MEnpjOoooVjjGDQ*V&Ln(^~%@(+`&0LQAJq#pC<jL7B zrqcxp>7?Rsq^dlwZ!Q_+{m#<*Mn|VTRH;}QZA)ntp;+|~l<WCUv#+eCeu~5@ubj0g zj5LOiEIi6}q#iauC*HQy>z@V^X^qka@nx{njM1eNThZhZLmRPKdqU7zPk_!i_vR@R zm^?T(ahsym6or2a4qd;kZOQ&@Ud@a+pb(KcJ|P3Sd91>LNHKqw;+6ZQlH-3AzPmq( z$ym&)nVtp^-fO9URED)qWHXGxatcf%ktFt!Qaz&Rf4lX$x&YWN9Y?3b8wuuZ4%<DI zp!~9|i+L<_%o!A(IEzS2ptd%Nr9&r+jgQ>8oL}iRGdrMl2k6)#Y10Cz!S|ZI35MXc zy=KkE#vv4vEF=CZ<)@?<?U@#NyIDfZoyic73BR6*@w9gG9910%(zTQUmHl+$&asL> z4fX4pz~pLRNK{3<g2z<RsL^D*SMrTd=76_AQbF|+v1j+T{!EZDhBK{{OLX?&o5-y| z4ik|16Fu1ZLTj;*eWX5?UHZ+K2X;yqDJ^DK8CWa+x^6JALzD)_SCkiUhZ!4XCbmvz za=owQ;|#K+BZ;SfYSKW4EFSc15FR@!@cOAuJ+)^g-M_(hJ&wxoqzQLN%_;1$<Z6Pw zzi2o6uKFzh(F*5yu6g==%)JWiA6NDaJJZ8#&}>&N8#v6Kdkkaog7(sjet~rM%VI@0 zd_3Wtm$I_d=U8`Op}f4=fM>g}Z{aBRefPLoECK^z>|;OD<yK1AJD~bF@Cm~yA2+W* z@8{ppGF`qqxw*I-b@F-zG0T7)lmNy95{elIwCci*ua&eTKn9v=Mfu~ukO$FaVR!Cc z*o~zkzCc_-l+1aOW7jS8%ll5vcPbeRWa_tBGBRu=y`Ce>z}RZd)9Q1CdLFQ3Kdpu2 z)f<7YsYTn3kr2SbHL*q@6Ib5^MG^}274rJ^{ZqoVOt*YOx{$G?^he1pN_ZFP8@+g* z=FzhZ2enT<20_h1`=+%NkNNG^Rr(je%Xm#VSRL(Ks1GeOk8pMqS&{RzsUW7G?XVEO z!6PARX-rFr{3##xX=y%>7rR_fw6-F+%8{3cw&)UcQ8>SYJ=x2>Rsv>%swPlzD@5pm zQXTt@yXDXoY;*YfhGfyUEyWwf^phN`0V5fdzE>pyA{Nc+J1vw~^3}QrRTXfrMPJ6s zj#0L04l$C*7TQ*A{L|H-U&M0#kIs`CCmQCAUe&0l(@eUvvDFpn4|2eBwh#+`+0%xi z6`}u{sDc<E#@~UlaiO>{KHG}n)?YCa`5Eg8>OYx|DWxA;lw4v54<qi}<5tF-V~fCP ztnw~I-Q`wo0QroEWb&qS^jdIMN*hKQY1$`^NMnf1o}O)bMZX3F?U#(18%1z2y$T2m z>SQdWAYAyurKP8eT7ayM7#*FM;)K%1ElAGl-N-(u62b88fY$l^_Zh;sq%yy5^B!(j zys<O;NW(IRjpXTEptrw_X$DH<k19@sw{p#(k2x^Y7iS1c&^vI&fcO-r!ealbs1N7F z$Nb!9zS`49x_BM7^OD+P6d_DB54^GDGT^kVsg16f)bhlSh05rsjN9jjBJT%R34K;A zjATEIH=KgRY}MjOAK7&2@5N%5x^IU+K@{!|EA&20%k_gFrUvxoT4WtqYvKon_mRmi zfdB3c;vU>jC{G=^9^_a}CFJi|uQf=R+pECnV>o2A2_;bHl{SE?$9x3|2kNwN$9p2e zT@W`QZYZh<v~W9xLG&@i1T?)a1D7>|dx%v-%t2Rt0tS+@u|dPhC0;c|iWkM`<(9LD zw*-Sry_<gVr)hqQvIS-r`(FR^75+n|%+3i`XC{JqAU(a*5B)0cn-Q}`%%MDCm|3D+ z0ZRcT=`UCpKdjr6l(*u*Pl-f{_LTs}>DS8(^l&(ga!3A_<IA?lq;eu8B*)`%NkI(_ zO*E>*wdJ?FqL9(*;$;B{qv;%BfGU7;Q(GT{HA~>I0yl<%*9RJuIW?(Cu8_o0&~T`j zDk8n=k?>CU+kXTq@)x%mvL+b8aYH-Q_lq-PK3=2RP3Sso+?!KCfc|P$3OtsM;(OuJ zoAJJ64H}jR`>{GeYM}|rg*FHA@U6qg*YQEkjb5j}+y^|j1TZdAl%g#@vZV(V1roRn zAJ*6cn7a<4e*8@s2=N1WTe@ZtQ4Hyx@+d8io)X>oZlLTXzCnzPzO|LU4bUcBv4;(A zqZ)Gzx4Zh~$BXC-3acu=N!~0$t+BS`Oe_7&O>!u$rwn%I^6MEV-S$DiGx3>7hsxS^ z$3i8}Bxo$W{%$+`vktN-F!D`mf=#^}KIT$Xx*(4|ZHpVki7_wpYUc0U0s8nithqz^ zyy%A9QwGVQ-cejyqt2S-yK@b7{qH4=y-{mGitBvZFu4x;uks=kPH_n1GF{_~UbB*n zR}Vpw#E`vIqIo#<ZZI!GVFN{8DLugj*4WV$TOd8@KoI$ZrD0!2<9uA=Ad+ve7QB&C zE_fe`(L=|?FUzHdVwx)?3+(FuvahhHIS7BB3e3;|Jb{fnp;p~3B`)#$%|vdI6r?`g ze`^(5ULYYj@+uhUBY$OxW%x5@v3R?eTvQHN2QADWjY>h~jFpr18?4O+S#EL%O>s7q zTvPgU<*LaeMk`<Xk?SEOiP$<WYv%F<fc+2xY`z1ACHD4H;z+h@SfPw>N8x}+Pyrmw zU6P-zSDOB~1`tSV?8ZuDVN^x{2Ixmn-@lAsQZ?OU^149@p;{b39M!_Fa;*UYpxfst zgRMvbof?$TLJkM}9>8h(wMNhOR2gfiFAkA|{3itg(p)2gw^Xx-of@b=RWf^hfc2g@ zYa%{75{4lrOuxaY@&-zZFr6~TS=u(~dbFyB4-Baap>nF*_>yRH>lX(bHU)(|ELa$q zj1iHr`AzQHE-1c~CCHJI)QM=N2Rj!kov4l-lpM8e=($l77Jpa~sNrvHSHfhPOAer4 z+aLrowQ*TI2G^)FrZ6UMh~C|EnGA$;cf!cT5Sitl2Aj{9kLVvhBit~>b99Nu$d+Q- zH@f0S07yZcELAQ8h-Hz!rbf^JUVX@ljLid^4c_o^fSVl4+KK}h_jC`;-^;Ryp>|%G zXK<kcTua`=1>3M{t2TK`cl=l39!1r0C7MBX4sXt8V<!ERgTwnUCmT1!GN!Ji_YIo% zy~I=cgcp^4uOl&b`P4%bQYG4<R`;&O4ai||0!w@r(U7XSC2eBmVY!QjbxUTsIN$I? z>a2K5c`MU(G0xz%Nc*dX3NXJJ1j=QEcl@&ABaqsS4LqM$u&~f$Sef+?#W1%CC!_-6 za*cM#K(jwBoWcrsmDB-&gE#8vVRuf$(W2^<6ERv#L=itJc|u>6CMkr<{1oG`i%YVG zDaja{OsRj{8GFR_A<PI*kf-4NV)}VUom72ICkTAAms4CgU%eym5Wha?A~X^aE{3m1 zr31yELmg2&e1KBr{TDwl4hC}p`;QFbPaZ5xmKNWQ<wTzxROf%Y8Rg--;`$wxreA#4 zB2$Sv7S6JmcwlNoB1%87g&-xH?byngH)mfkZiFr>wi3G0IMvvfj;VEL8oIO#=Wz|i z;WP}E_V<KDV%%WGQ38(0{#fmkj=4%?!^!eHMcsWi(f*(0u;q{SnZ=?gfg(p2xL8*j zQUTLb7O;?Od@hz3qYsP24c)x_7lQ^G5W*MWzk&Dnx9miX@~ifcAP2!HFnjM+Vg{#h zwrsjsm!5aC)GAZa)0kAS^xeuOlCkfOo_`efYc27JhJpJ_fdyzVXW$o^qMlCjf9Qr| zo|(5C`w@dB`{c~-ghKTa8=2P~p3M0#i?v?D51;of&&lKkLwV&?NT{0p-T%z&8TL{V zXS#2l;nyVZLueKjl-_`Xu@_K%Gu!#a+WoC|(snu2#tbU<4PboYi*@BZ_0!Z^*1U7j zvZ5_#D^3dmzCp@&En*&+qmlD*sfq(cV8|l{_L3+6yI*9knW(q{U3o1_t<a#H(SF@j zBHoS$39N`bGRaScd<IXQ>FgYlHy<~kLMQAn1-~A;Jo95OmRLcf?$Bl;_nSLrq{)yk zS@s6@bHJjmedCA5YII@pc(OSJ<`LXj76yfv%DJ_;$gggzXG?q%2JE`IgtgD=Cju00 zH@#&u0o0g!JS6*SO!63QF`fAUiJA60e{80qtohrAfYcg_VV#m)Sk7iYoOYcN7;_kl z{@n!FT>H^MyjYGGTT_6pV+r+6LvLsIF~y5T8PY(X_)YIY%W>6af^d>&ztW*_z7%Or zI-g-SX*ufF%|^39@&?hCg(K5;kzS5IKXYIIJplfNFZ;q1Wl>jWa5dvh_QE2^J(<}S zWp}l@8}OCV(&yTkt(^il7s&8j6}q#y6BOdgKtpsKs&40^9PMInwRy7mM!cn|(zc@- zV?o2#;?D@#)o{@PwM<wQ2^L*nn$CI*y9`NMAX3%-d=wlHx>t(|U3)?q`%s$`96XDf ztVb0u{626)@ff&AUXuk2!ehaC*br+7b}E&j>06uko-O#B0(`TI!TQnvJf7(!w?@5p zo*S?zr1={t;QT6|cq1Oirvk@hB((*P(#X~Nd*%CvDE_c1;_z9V6DG2fTQ?R?hNG|L zc20zq1TBw5nGkY#u|%`UVYsW>y<bO60Ke)$Gff>3x2`-C;1KIYEKy}=--sDH*jZkW zsBm-dZ~5aEhWB0GC|;TEF4>-@a5j#-Ldp_hS;L>lWn3mGOl}Scmo|r+X;-`tKF0R? zh)xub6jJw=*I-mM*_Sf{nHjCL;9dp!3^lG%rNC%PlIkc#5Zd9@C^HNHd<U&XEqKA# zBAqa>I&U7Sm}KBBUy6MwNog(eXbh|3Cvb6CYOW}+P#90WEZJfi%&hL$S<`iqdxON6 zN)&VyE?;%iOdP*S(QTsqPN9lNJAs%Bg^hBr4lwYftj~~*$TU1mr{Ot`wKrMYim(<6 z(bmtcv4?7!0>p6iBBs}}C=NVv!ZmLBV^It~zG?a*4qDJQ?}05}iy*KDG>VPzU;nZ- zX@Y>5yyWtAXpJj7W4ERz>e8G9y44n3QHp;52#6+7CzojaJ3%6|MID^Vcuh+)pNaX5 zN*{+RJ_nCT2sIo&#LWR*2RmJDz*CB%ht(|+W9vj<ZgFcvYsSgD<+Qk(^jv}atv7_~ z0foJJi70^|B&=iarW&g?1(L;=T+n|rS_M^MeU)aXSN5_tvUQbya(EE+Jl3#CZi_L9 zaPKrwo|%CzMRAW9V*46)u+SFGS~VsJWgQq;Q(hcRCEH<J;lSx%Vi|9q(E8RYH*7I1 zLB+4Nn?uX@x@md5JgbS#RCfmf64dvTk}uk20ws?VbAS?VL>n0$*x{IHyTU%?4T)}p z{oEgVGt}59*qErwvj({Fp2y-~e{%A5S$ISU<yHy_mh}=+osS7aZF}ZUm6HkZKX-zx z1YJ}l(2B@&*ljb(&ALUwHNPVg(BRlcY-S~2B*hUOW{<I*csE=G>HMHk4=7bP*{HW@ zE_JZEn#|{~0x|&DeLH|?Z<wlDC3^zm+VC!A{$goCnnWZ3harAi0FFyU9nr3I55i<s z_^U=xzQ+9YNguuHTo;L0+7_@}eauW+;a2}QO=;aIiXAt-eNM9oqzXH6FQO`Ts}k^{ zjSJj}nq?Ehe*nGi9)e2(`91u#*{x~_L#mo)kNdp5y$L7<4!|2a^tZ5>`v->RL_FrI z!-8&#q$;70$F+(HXlvM^fRhD%y=m6>7pnX*wGF9tP!h;cDv$cRr-kU38_yxpq%`&m z{9?m1?<D`A_%PnwjgynK;MdFUBMh10FEpifzst}sZ|#wxI-g<9dW^)X2+qfytMb~? z(N9iyB&M3g;9dX%%(PI%fXLo85(mtnAlh$NLIUkDM1N_np*0R$j6lZq58uW+Y{WC( zE9u`hT@ABpIm83Cdp;%Gx$dW|-D<d3jV2F<AXKSu{)?3Gp{=q$0O%PVS)Tm}jLOTC zc&-1h=V3`QuyuR5fwq`@ptHTkGgbOJ;q6+__kZ$N;fO-OrqCVWxbKpnU&K!oq$gfl z5q~RgRx`4mnFc8Ve~q=}E@5@1Lu#jpq38c5@$fz~$x-Ih@(O?H3Pr{(L<v|_R56@B z&132mYq|^14eqmTrz9j^vWqXsKO}C?<+mQJ@Dry%l#_}Gj5*qLuH^Y7?^31IhA^MH z#3<DQrXcc;lQ8|=SYq$XRSmXbt}H_z8{!}Rc50&J4#n662`0>?$tBf>0z4LtVzX=* z*8v75v<N+uhm!g~5U558hiiYHuDK$2X+7bvTjW^+zb_rPz#L;C=gKTq0%K;bKIb9E zZD%@_J_&hsU%iYS>1;eG27*J>bAi8YADWd$l;ym(Da??1KOVDiz1B`jpXep7EWs14 zQxviOtW<eIZZt?N`C!A_#yz6HXD3(mrEwr4F9rJib00T~3dL>Ge7a+o*S4J95gE6k zE|B2xOb_Ut9;3@=+P>5wD>`T9K}~Qc`QM<*0QpWFSPQ4MQT8L~_tOWE1nSdcp(NNG z9+Yp5V75g=Qi_G4lC5ZD+QIh@prmFI9Yz9B-t>-)o9*@%{I!Dc%`Hko4)C!b`F8C6 zNT$5EujR?CkW}}mezou1=_<_J?_*Ih^KLm!G}M>D9>glt>Gy(!v*Fao!e)hjde}nK znRu!zX<KOqXV^%r`M!MaD;A2lA<X@E`}p`ju`vY<@3WjoYlNlbypB*}rDh7g!#HUD z?Ej`RFOqFj7lRXk{wh+aLlfm~el@Bb_s1B8#aev)OK<EbI1v^|QGdCFi1L=C`q+rg z4_<g(rU?spOUTMCG_4hl2axAif*pI>T$#<fMXbfvs2v3F*ett0vm>FHd^(uK+`1G0 z+0V9-YzF0Cmjv@+r>L}cKZfYG#PvQ*Ah8nuT0H?F=Ju#B$qS1hwfzb7$|W8$v1nnO zY^&=bLJO(FlPV)lC1!?C>QgW7zeHZz={p7H*b@XWFbx)Cw{{6f>mO7v!p&=nu9-d6 z8CxQ`@m@VZ+puN!9w&&diEBp6OvCGs87pm)UfX<McH)e(<6qbW{Z_GTW8WE>PH?8G zCdrI!n`d+j)a4zXCpV~Y3WjXvagGE@69Dd6H;?XCVRT_xK{|cVc>Tt~A8&UTjPZV{ zipz=hM{H}WLaeSB)6$YCKlY0XAAxi2ZZ*XmX^4Gd%?VVr)R&2vW%v+Tpjd1=eVHSK z;U><3a?fV--}?k|Aqb7S@~HVS!~v7X(SlCo&Zm{TUov19jj#;NWofYSt+YQ~d?t1y zt#v2aHEs!kQ-7?7Q8VzpKw<t<_k~Q?c#e_md(MNegkS5*yR)?&L2{O4XWQ!+T|th_ z^}ijV51}q4!DKLD^D6uid2w}lqe}lE73S#ik6=cnBuIh;0{8&d!Ml_LuiwU`ZYMgM zG}J;W=Ans<v6GRlP9fS!SK!y0q>tYZugpdxanX3sGpxe=bItF9Pg>dJx%kgleGuTZ zw{HP?N0sDN-x><g&324Le;!LyhyE=b(?&Q~J1;Bi>NG5!)Vme}1~pec)+HEBy7Hd# zav?C!<Cmso#{T9qY+B}1mNHa<9QpOeKvHeT1@(kLNK-X9-f3cB>c9VL*Ro8x-@`Wp ztuQw^+?*~m!dvM^i-x|g6DDL7Ab5=&m%14nM80815Rwqhaq^10!YX1*qP-X`4=^C; zsnk&c(L(m?vN6+o<qhZ3jYzP1*pWv@jDyj#A~K=yp=*?|O3F7%Cg=iHZ`xb!$Q1@* zuweO$@l!lWd`QU~e)7ml{Xvqp1U<xUvfn1z;#X7;BEr%+6*~T%^`64TdDdDO1<&#H zT3SfSUhn~h6HRAO+H#I>^ymeTz#USkRL>F{pus2;nIcwQ?0&<(TW5R;ADx9?;~YB) z0l;+@YB)5$UgB;`gGW~|1=70Qf_yAz{B4#{|6w?)S<wUGjgdH|ks`ziOaJ+5APOnw zjz<EaAQ-O*haT)(z9A7y0H_GD1cZR)N<~)$8NKPn_3LD7WxMzNpSSs}7c{0^4@Vs9 zw?WpH^aZ{lMfTb<D>&mg*|n1Cac`pmV!==lvK9r$={s|jg;yHXA!0ydt^nlnvjBXd zn%IZ&T2(|UezU})&}yT?e;0B`+HZ%7#hAof5K&pR)6Nuj%Uw_2hq+JA2$HPGVi+IZ zzPirNy%z>86GXpMUPN4OAjf+UYR9&n7fmQoG(PGhT||YeZ@`<zIJ~p@se0HsNBVlR zX=qTwNS-;>r>>>4;kosH%0U2ZqeFG9PX!%Xf1~gDTb1x)X!?!}1`{a#(Uh{~AlS4Z zZg4XwSZ%)=Qb=TcdW&N0^>97@YYTIbjo|4-iI`BlR2ccyZHDa0Ag>v5XR@~w^_2~| zCsm<n4m4=PLpbW7hy#oxDW}yAC<j(AQHxQCt(&hMj9QOYY{1qEe{T>O0e_j_<v>l! z(c7f~4-NutfCr2MwvSiDw*!`4VR6wjh?sb`IF5=2?#5Y>%7m6@eVp!*;mKRn=#173 zt1bK~KyVD9RW8*96RY%783It_>gdQ!Lmn^9yNrPF)f;aEkI7;(77I?}>d)*qSB9c( zS}(Tl2^YhE3?I#kUTrseZ52}^Sgc^OWXxOdsWJQ|-jtnFec0h;38w8QAB=AKS`<Bs z&)Iy2(dDnU6Ya1IAERk+t>zI3KPyw4$f_B;>)wiOX${tkJg`}6R(Hd=QtKu+oU0$| z!V-nfsJWpaAj6;x2ScU#SRN)xp})S=^K`zqCsnT#LHnx|t2x!TmpIe12Bo{~%6k-c zvX6LNx8|l|3CK0yU}&>|Fykxab>qo@XDjW+zjNl7$CYr>xo}^(n%wwU-(li-1}P4a zj>t)?ae(AhAj#<~TJ5Dqsf2@}7cQBaNsn!D3S+F5YIDCgN9a3Lt4J(&*`H25e&a~^ zMxe8TeI@wnRFR`3AmK8LY>4Z<ktw8iA|c@ij(*2zgr>JvcN~fPKDEWcgB5oqjCV}N z;sMlZAAicD=(dUl!crq{lEuqz06JXi2gHL;yxu1bF7%YRD3!u<?7+u_!G6tGTsP^f z;`05nyV^7#5W6kzl#kJwFU8T84F6WjmX<*Av1G)<`k_)+Fj|_m#V4(d!I97%xwgVp zBOe_-7rSmhwCqEnZD<5xTAvyk`9#8Ek57=<%?PxlbAy?#F6aJeADhRKt6x-U`@<fJ zKmOfj(G;6HxkQPZ+XHuAw&$x*XWE!yqJetN-BMf{k_;HPCzb1~V^0d^ukb&lil>w! zvHpYve;7OW;=N%|pToFzT5gQ?DA^cU+XG(DC&>;4(>Sgj)&9lP3c++uaCNf$$6ro& zSg(wXMhL)Ry%@6;+y}?CDlJukhL#{acgMdx?V3J&<TM7<Czn|S!O}uhbnNpV<oKfD z<ia-x|9e!f{4dk}wRC|PGK{i5f<@=y-m$&Z+tShq*bT1HVN!*Mfwt2X19Y-JT)S;O zqh46Z#Pr!J<pphJ=FZW~R6PEOa)P@e@z^Z9N<7xu)0tD%tH+clf|nj<0y{oi$4Z)x z3i>x`>_iV?OwbEpzd_)fY+t@wP6p=F(yI(zB6zu|BQ-jztV<Zd^6{-zqe-g_ZF0P2 zDIz|UiV{13`OGO4`|+A*;km~~E~>4jGShT_M{1C{N|%;#kfq2Z1*V4KebWzLBw3H? z^R2k*K8JoFRDQ3wt<WSm$R_@3R9m?wOQP3nC0J<do26UoEHi}msq8aWzmXtCM?j~h zvEUBrZH5JXeV)oKj5)wJ%{n|*aHvFK^f$vOwGi9(1eC;T_a*SA5x$1OwUP_hBq#0X zsMh5FI)h~jN#zdcWWt>OB&46&o6eN_VnAE=1GO_I*m17zPFFS%fbs|Ka2%%i`o)IQ z4pm4eZsC6bS%eYw+r-9VI?49&D)jK@Zb?~LHrMNFph_3&Qp};Ba0@MIiJe&F_em6+ z87W<7jL?n*3@|}2qqbPv4d!5Oz0fsTlC)AJSw>es=GTlwANiDuJo70&D8Q0v$5hAJ zV24fI+wPcF91~K!j86s(k{hIUaexs{?0EcM66YZ9k+s@N9V6RCeicr<cb$DQxk`iM z`X`NPrdQN={&fHrtjBzT0=a*Ce4wAtT<^xygNwwq^@nahdjGsu>nH!eJx9#d^*&${ z)}1wubiB|&`r?&-+BJyC^vMBL9)=?UFQb5{!OqzA3TrIX@6^K7UxUryp*08mnjpj- zty3~8HeeQ1zj=4<0cs+M;s8u*0u#bcc4tyI!oJo3Zy8*ZYoDip2A@Nl^Ak;`OI^=0 zet4)tD<e3MAMcITGi_0MGns8g!AC=Aze`_ajYi7?D6*6#B_F4~;risLwgI=-A)7Fm z;@T<anp_Hp3a%x&t|&v>`Zy6{SLEVVWwrq9BT?CMWV|vSKnleZ%5q}~!w?VW*`f`5 zC2ws^via}iL~6uuh)24)<66048dzy)zjUo-YJUd_DQbuJCl+{$u8Vwjb&j~SrJL*P z3U@O07Q+nQcrF5rfXJ8$cPe$aU^eWfGO+dXk>8(T@7fs_54Od^ufC11i|XY|qR%1! z{wM61E|=fl<>+JPlk0KXD{w{w@LvcT<=Enh0goUH)4UQ2tJc6_R9a9qRi7!S<eJQ@ zA!rpgp6}!j3CV~@rLdD^O~SxnZ))lTbNJ5m^jjzRFf&hIw;V6!v~RgAc;m4l61=ac zhQ8G>CgTCc$gtZSqepou$>A><0$u3!EsY$|L>TFDqp-LoC!+r2YM_n8$6mrA1wAbW zD1^Rx8jEddqh={UJvMn^s~L5}mktsN7!msuv*YT7WM7Z{A_FDp2j(ECZV4;)B9m=| zekH&D#UeoqoWa=?+P?G^Y(*+-XA?EOktT93q>vh>KtetIT)f$-n+u>m<%`lm1xGZ_ zNL*1#tQm@Kh+|<bdLjal*`F@$Kw_+N9?JRnhHz{?=v$OZ>~!vV*Qa!{n@no(J@khA zad~S3OW$fO>|mBKl7T>_5Ahn6AJdVQ$2phWvsQjyq-QX;pXvp-Bx@(R8f-tt8V*+Y znWqTnp=p|4x>6wl|H{aNbZO3S06vXK$N3KtUKs*IE`LO`k0eX@I(@bO_p{P7y?ih> zS~A%x9v{$qGb3qxX#Q}@?n}0(BXPWuFYI?G+0`5GTbb*R>052G!q_Lo@c$Tt%{h63 z!6lweQKuGp0j$Os1FR}fXEY$d#zmVfvU?$vweVwH%dbyeFNkx!TjdKVQ{}R8(}{DG z)tPRR=-o)c8hu9sj`Ur~S!FFvG4b9yvCisN1y!vHO?<mrH9aMCnx0MS<@OQFWsziQ zF1IZ>yY~th`$57vW(}E&#)EzCIw1Yp4|#&Xjrab(4!nHXm2XyF%VTNluIbSYU;FTS z4nAJk{JbJ+jtkECADr~dv_fN146@3wRkldQRI|l=ozI_|RN_4+A<$BRH-{-m+@2G? zvDwyYI$Ld^4u3X~nfaolZG^COgDxr8mV{RRe5mNQ`J$f!ymi^)OjN}RYc2{lnK}a6 z&1fU$$(_+9_NwP^+EXWYUp;ORwd^?aY)`oZ{39R{nJ>4uf4!zTv71n<B@HL`cacRg z+%gL~8#zcyn!3_(l@E>4XS5hi;F^b7TAhm|0h&fABaFh2Ca#l99x%6C!Y2q^@hbl1 zZ8Asb>kU?L3hJsBkrOh+r7|9vRl5C?h^q%&5@w`RtnQ%Oi1$kzmx>62!xlyd61ODZ zVOGL8P!B2={oRm~=D6Fqo7@AI)+NqJf-Qm=Z3Rr<RmyKJ`CnNSij_6j9^p}r*=IF9 z;=@@N`@MvspN%-Q92{AzHvmJ5htaxIb#IfmtH|K%WFn61x?PU38pJ&R<5*~Mef1sN z2G+9Uzzs*?X7pMuL2~2Ah(o7IdeaWfblhv_@a7I_IB019NZV#!=8w&vC|p@~Hx$QS za)eK{Wt{wt`hD63>0TP>DxO7`66bullHFQMDa1XH5ettHhsbp!Pj*X{8*{+umtp3w zt{a*?c{xi7z+#Ho(#Aq6#LKGd4&kg<szDGtH{k5++D%GlwSSO;T#mk)KNO1!R4Zfy zTph{gP5R!-k56&a;mm`+&u<w1%Of@Wl<xn)vSLNBH>+$@9yPH_m}*m+$$K+uR0wa5 zZaSKF;>3nl{mW?4*c%SL*rvekV;I@~$4s3q%gH!=DJ~o}_+=bS&;~UVT(&<yl!ug1 zJ;G|g>ZDQ(tE1u5H+Ol=G93`};TPyY&%Q8|r<G>X4Z<Wz&Be07H~P)5f~$3&_LdZ6 zVI{Ajv>LD5*cxZSIP$?hu>gzR;(u{YEFoN6AFmg`@S}0^?F?#sx8x5@K5ex1?OOd6 zDvDVwLc)(F%^cHNa&`rXHMih)UTniLzno!siZN)KVuiK|L|Ym+A%lK4%VF6*?19)z z7njxsp%D-(X>jHgl=(yF4+4^aC4=`jBA}GYFK6YF^a+OR6vN)+rs68zn-Iy@-UTx3 z+M7D_LhmR`H9lB=(&>ueDTRsJ!mnB6GIy0+fY?gvFL|lsBc>{%rwPU3LnA0O^p>eJ zw5alVY(PI{s)@T7II}zDtl>a}&_xY^EXkg03IdZ3z7yt1ZqGIllHwIG&$Cnikl0an z+P54}-=w7_q|Ygk!S!gSG<}*-h|J}(Qc!4BrqI%hg&6(PM6J5}J!un%DOCd&P}$~l z4o0q-zVtnK359LeVs!u=rscUndvxd}JS2uvteh1>{dgNGW>YF(hlLrukNM>e5k&?B z;mNv2D1gBl8z4RRNa=Zs8ABUs`Um$c1&B`;)gl~R6qV-5drl;aZ~DsyTu<us(Z8uC z6__bz_qSIG-kQod2QTs#yVWRYcGwBo$-1@HYNO3N-ddcC99Txrbio!zn`pWi#K?qr z_wUn{?B2?glhfgUQKZ@vcl~{PkRrSo&uZQM2;B7I$f-HU>2y~^N&G!)Ap<!R44e5k z&vo$kMTUN>xA^2lwGV@Ro&0Dly{bx??W`HQJ@H0tmNmbl%5KrLUGej(&l&4_9)x$T zy|Yz@)=;bTHpcxOZQJ^)p>h-16YWiF>kW(em<}b+L8Ed29JlXp4t8Ph(m*+52r&S+ z$y5cbagD7hz=ep@bRmSBd;pI5W(W#=fa59=SJ>mf9GcaI&Z|HU;DG(P4-&>BkhO8t z&Q~#Q&_1HPae(`&UY1sl)x+jFv5;T5zYAjR(|*SL{3A>B_j3L8@x0hS6`7^Rcmw>< zxe3Thv6=^+J3`fwUFzjdQP_$b%TmR*&8f(g8{JJVMQZAO9&5@H$eHw7Os|WN_vuy; zKxN|_28Oa3{R(~&TSoYTG51A%pC1dLo;=Q@i6SMBe3`m}@4i1O;C$-3E!J_{+?~q; zm{1;yDR1oFXZKCe#Bg#AkyJX*nj~~ZrWK@K(?nU(;-jCG9r%nfK)9AoTCC7L2)63m z1D9r<>gvtCgXTygm!OL*oW$<l&mH5;y_aD1zOM1+x4?w-LDhBPJ!y9}s{m+Z2kj_? zs9;L3Mq?%nNZ6}J<+lsaLDMet{pmux9aBc2Fb|K=C>M+u-TCV7VZV<$NK#m-#!e^V zo6WfcX=Kd~eUu=6+B1bwkiNxZuND5Pa3!FJAN9&Y6~86}^Y7rj$Ca55peKNHCtyX} z)%V@)Gitd0>_Kvx0Jh;mbDP(6q}WUQpp|;XxLalzk7u86EB!vKoS*Mp-3<^OH`R>X zeA%wb^Ic)z2dK{>TY#PP0+eN(2aEWUK#SVBmPhlA_d}&;7e`-~E9aP=Qs5_@pv@o^ zQcA!MK9Nrs)S=jz7m<6*wNd@L4>yM$j()F=VI0Eu#!TUFru@E=`l|=(!9UquiWu;r z1+y6+aq@T_hn`-hfrUy(_zK-c)$;+c#b6lOog>^l90`QbF|4G<rA`R;Pem|{7tqBO z?K`7pH*b%=zI<0jUR>`1dt<rXxM`kcKZ^Mdtb{cY$rStE+<}l8Djw<PRZ*xz3(re@ zYOIy^T)HT70kKhsr1N*NpO!V?7W^Mu>_V2tHOJ2Tv>Il;laqAEU-QQMr@2;_RYdcE zHPIa`tfUdYxHMnbi?ZkTk-FHZSorsQfLXhWDT96MY~baG{YBo4%gT}z&we^lJ(YN> zkG~b})APNw&K3NXhsNFpT~6S+0?{}U#0RM=j$6>8gz)!5(%u58?)q>n6;}PIU+$%S zBiO(#RqGL%#fMA;f)-&;bM2Lyg49$knI4Iqpa!|vC-5THBaT>7>%XB)`I`6kZg=A^ zjn@ME0lOFteu0Ngp&#H%w#OASF<stD+(Fk$PVls;KJx$^A0c67h$hiwSs46p=$A~; zDuh89H7PyKgeq?*{Lmft24`V%YM|n?e!+Tkhlh13o<Wt|6wUcsae4~Niupe1GJ4`! zFas^%eMhP-Q)P&(3Ro+lID!n}wdPib27iK>6h9X%5?U^5u$4VIza}OP-acHlFcz{^ zCBDI=<7g3NQ~wcumJashg{9`#gUyF`223<EasLg9&M@?4X1@e<)S8HCwYkGrYUbrK zQe}^PMzV$z?j#DXn`;WHd<l)y5v;+^?3-|@kH&zZ4xH{CBOA3qtJx;<Z47y(i-v}2 z&I1=O&5p@Wu&>g->NQ5|BRD-WX^mgD*(kwLm}exi8!_k=R#EY{HtD4Gt;(&Qj#A?s zsum3)2QJ|^kCAkQ1PmMG;WX~$tX)1Ear&bQhk5j3ROt)}KX@;HBDn9Yh9YDQdR;+W z0{*B9FbY(jE=p`&g?<bQq32>+su$yac2O|0k}K;~3XYLVsU~FsmB0*hgAz-}2x)Z% zRTHuDmJ9ntsms1X71@PM%6At0mqW)mx$)sW7(kBl;9n)3nwhEhG1QF5{mi6T#nE{R zk3h5{T0OJBa;K#y)-F-&l9;47(WmnIWyRDGOmrhg9$w}C|3IHdPWsz~!<V<Cnu7N( zZrcqWu-16nZ0MB}zaMDc>5n!<&v$=RruRPqk$<b_E&KpJOF{|&Ezl`!(#eH;1zfkZ z?erEvZvAn>9>R-*&8o}q(G)4vTd&*B*w{E)Zh8Qpy;|Zk<Gitc2DnZMmHqVd7J5mA zh#}_!=qZPVz;0f?aTeo$$%=Z<&b#^2RP}QOJLJcFjN=4RXB8B9fGK;Y{?Uu+)!f7e zD8Q_0<o}{<^T_1VWjXPIt7Z5mv&8{G_^`nP;p|?vte>xK%&|N^d<ko|P>b8Gnm=r3 zoZXL(AX4yQ%_)mB;_x(kr$H2wpXJBMX1l^IFtE}I-vA}Rs+gffdggp!eqL}oV!#1Q zi0h4k=(i#6qslKVJv?%(IBBswJm)_U9~<y7Etrx+Jvp8GwfN(O#Dwo9t0?K1<W^wv zaeIJGE01H0*b4mXqyn%}Bx!jn{ONptaoiXJbL3`#nPLtJ60^)vuL}hCX>PaRXcm?i z^mM?*+V|0)MzEBh0uKFDv?Z8dpW}M}Jyu*dxL62#HvG8ssuSo__!7|mM~veHLDE`k zY++c89-zK4wrV>>a_=G@Zsan6Os6C8m(xE0kv{~2fYQ%A-n94lXS2xQYuZgZmnl5% zTe9;U6+xLICiT&|aI<62#_<83z$UmZ(`=<z{8x$`)NJ@aVf(YIv?^l|s@qee)P8K` zNrDG|R~@<j4;2_+Jo>KWg%!aThK+ZsgOgJf!CJT^%jVReVI!i|?jaQ*I*?|l0e}nd z3+MCaAqDh4<bw-1Pw-zMo;{G1Hxt+{B9PYpPK}akV3yA`8VN8xe^}|5@Q|=ZV_(VB zO19xYx5X-WO#2#-Gj*rPe7IonX#;3v7xvWaj-pIqw59^9P)_-$EVZ}5D^-g3Q&u4r zk}KZqR=CZ$d70(x-u*`pd;)}PobOfJ-srWu0ZM#s|C_;=aC&=HWsv2|g_>;l>WO+a z?WU-LEd%d?7Gm=a^qAQX>^+TvkjKN~PqttB_xC<5d8QHuZc0l!sy~!VT$AT0x*4V_ zpPd?D7bj|f8m?&f0G|U(3g#M;w9dW59Ugk5Ar&L22a4n6oFIGg!|dq6Dp7Wn)>8-! za;xdHSV1K8)9sFn@E~bK5V=AwiRyMCrVWW3k39Y|Mq=+Fx}$EV>IDE}@Umz5kSyNP zq)Kt}%f)Llurn+boTiQ?URgtU1?lLTxSGNV>~}!Sp%64oPgaZixgDGxrX=IsOF*$_ zw}KVFYcmVG#n6N!Y6U-WSNp^suP>A*(BmIKzMvzr^H0fTWUCWXAQkIsxyF`Uro9Ga zC}Lm2ypXIXy3&9Wv}E6Yo#X9o$1+FFl$&NG<zOl0G<!ZKg4<C}dW}FKBfKzs>+=L7 zF>njys6QXJ15+MS(S~>sDVH7NhA#?5;yBx2p2ycd`(%8TgVk@Bf6Zhk%*4D$Irf~x z6q*wyQ&)^I8^Zi2Sfpozs=Wikr9Lo_$;<(1c}$trmy}@FDv+dD_M#`q*F-89N8BI* zH^qw`?d8WIosGV^x%GrN%mA_uDgnJ$^J=+DVQybSV`13nl`|#=T|@4{1_@=L8ckj| zV`Tb<tyDH^Ldp|d3HrptDe~iO=NC@R5wQu2`0212GRiltlj9&D(v6p_FYz@{GBkmI z)ZArEGzAl?lJ=6?{Nl~UsTtD?$QZq@h%wpVAAJ(y0o$`~4rhoXAUcQ@Pjb=Gi~rvk zP6kWRRfZKXh^g2=y2kk79m~z*Fw<VCWM=ik09rrvbtQaEaiylLHq+7{TD&O5(s7Ub z;vl-!Bl|=MOwsVhCvV-JV_)g8fnal$(~m!j<9>}Puw+~D^NJU|kwZ93{1}zrscw(v zRNW9)AC`Y_sM#}fu2i{9pvoU4?6Jy0M;=r|aCmW*WJ&7TmlvREM4L`ycqj7`LJmwV zFZ$+|D_h3+k^Q6%$+JcN?|}qW1xJ~G0Ns|Ffg$S?SRcK|?Z4%161U9yYlMPYflAMD zd2cycsroh%;_kgBcIM8+>fN+eZ4xx&)9>Smc5>weup~7xB6eeBeBTVCOUK`zy0?v5 zC^W)4=6t#*aD<d5@X1{*bpy2MyDKs_0W&?oueZC}4&zLvALJ{!C*n4ysz1W`LxqUi z;HabL%lsORoqat*P#KDG^85o`d7U3XV-v<?AVeW_E(c0V0*z)i^87DHoae1cLp<x9 zxX!grgt|~mnq7B2@^hO#$RF8MUYOKH>?It~+rW3DV<Ao#Z0yzTp&3pS5%YG6^<N%M zwNwV&>^G;pdHO_nX^pWCehYKR^@f+x*14}I5QCxHW}4|_RjE(VJB&HpaGmlLw&2MS z_{X$g?z#QBLikZG#&!W_Lq~sCl?dEs?FZ?V!zn&q`}P~vzS;+3n5<j^9w4=b<md}j zFBZq3yzw5O4H0pOOkG|M10l|~Q!hQzA&qKDGeY*QGenTrBpKH!?Yy_qIy;L~y$$JR zetK~NIY`XFrusv(M5DUih||T>OThOAoG=U*(0esLEs+ygZATqD`8{`Z7LNhc-1b~0 z5`x{^z7mu>4+kJfkp6yQ|F5l$?*C^ecmvFIZlI*8?fDea1Q$Ijj@w9>T%A@R9Fk2s z@3C5tYuZvksa~&^LH#Wr_;#s!)qv5!Kz}L=AfOC3vz;;+?k1dR_)to_)4br*sQ9@| z#ek!!<(>OOft5&veQyA^ur}<gN<bj4(mc&i9f}<E|M|$LXzCXTGg}&UlJITsbm>is zNUvs@%VIRvTey<C(_NzJ02szTq!;RRG7*0AET5?RAuCLnr&P^Nh#07ql?lp_pDgGK zY4>>N9KuKw9bV}&r8<J3UF{$tcesreCBFlLuBo7|glFh2vK-(n%->bypZRWKSh7q0 zFy8WozPEdah?Ig;{Sc6>r*{?=)Y%on^xzNkHy0`Wk<n}~L+ZK#(zHpI9Eu7ZX`}A= zu4_Elcfx3{9ZD^c$HNtjxa4#uV6E!vq!il~ZdAf_A9U8L!hI}3gp2H`o`GG;Si(ap z)9!vt|3cmbijs~7A*E&$7Y8MMJQi6|P>6h=d9@a?!k5h_pdr+c1Edej5}+lPnQfs$ zn-oS~u9nGDo51+^>xSUTqK_d}Yi3#t)iD|g&e#J7S(7(vbMWlwxyrnNlAVAhx5Gv> z7peyXmLpaL9y81LrS!Z!SaVLMJa{(;FT*N{bY!ruGmS8)tI134adLxMgAf%Ky@4cL z0q3#%XZ<;t-wj>gGL8wX8&3X&D8@f()_(CXm2{goypYI4BCM0qRdyK_>F4~7+z4xg z7JEy4n4FhRB#Sr=^1kO30Du7$iHb?X%+}%1wdzEf&pt2ksn7api_FHfFvGnEJ*bwa zb?$*4>(^C~y4RkKv5>*HmiSmw!o)YhZ`vxXf|Km!2>pUUduItyT17-_$9D4PU)|d9 z7~icA5@{f(9M8rk3IHCi<SFT=rQV({;JLk3%=^N%rEvBIFQJAy4byaSb7sAxmm|Z- z2F|zDkYD(ytR@$&!u+@}?zlN_DF6FSWmoE2Ig@bluo0(!IRAc55|2+>JKETZKHwXl zd!^N<LrD=*PRIRCo@TrI(yF09wx!*DZ$WOnDTg2ZW+r$_l4X(U#^+=!vK`Z^`tw~V zgiOk)S>H;pXmD2GL4Szvse$x(0s*WgQ`#3wWiUKfn)CxA4R5I2ln^1~UQkoFjsb+% zcB6Hb^kF8I3*<S<+aEu`C)FP|^V#EK{pAvO-smY1)Vl~C-gY<lMx&hUU<9|1cTE{s zA5eu#p?a1y9BhY5Qw^g#$}ck{TRW1tw7mq0fS{4nQ5RNqEz;^xVw6<kWpxV#NMKOx z8W{FP=>p+%P0~T+7(T45yt@0Yce~uqsX|4<((m6XqP}mR_po|W%{Bq|RLIZCqkR3b z3c03=ISNDmr*T<f{T)Y1(g8CM88M?7;Ur22mumrm+>Giq!+!c1JuThEYciATI9El1 zxKx(a^I1K=L_<uq*#lY_?U2aYo|$|@oLFL68@{Y;AZGt(Lf2q`_&1%I1gGJsNWz4N ztPfPG`eeLqy!1Z8(w_oH{SvIj+hV__oIZKGS7z?Sxp!RwI?b;MJ$vu5$2_A6sR|0# zDL?=294vG~xo2hc;FjML2EzsK+DFYQSyeP-M#5;sL0j2Y(bMbQW}qHaTBcgs0Z)-} zdIjK5(WXtPdQg5{A1{_g^UE8tPcJ;Dcq=0G+>4LILPNk7>wK<az&*CmVq7d|&kZ8u zwQl5`I5-kHy4x4sS0|ToU8e@^pNfO2X6)MDw72<s1ll=#6K|`>wVvg8!vH1y1vFJH zG(UOz0bR1Q)QM+TniU_V;6irVVNd`7QvEVh)&e)&W;%~seniGXg+yi0*8mT}peqO& zCcrHemrD=zeD!irT*e}G@+fLl_>G{=k?lLC461qhEOPU6Y{fFo^aB8o#prpjz}M>% z5*MY~L2-80&6WISL*=5$hS+~Wg-@e`YuEk?p9#1^T-`-7AVX621_g-Xo0nHpu#pIj zWg<h1M^LC0Xg<s@B2`q~&5qx54a4|eg))tR3J4cSG!}$}AWoux4Dwr&vNkxpw}+=e z?dUfzI$pG2f+~-;;3`dUpXH0lZN88Bq)+e{`ZK`~*gy4L!eUC-No#8P8fD%x<$a-T zI3;V3%^EpyAV}AKuO)+-U0_YmMgT@}#%d<I|6ZX<#xG^+iFAl&-FCQ)CnR>Nef&Iz z?YOM7wY-t_!8SA0<by(L2Zp1Hxa_IU%R0Rh+SXEDeX%THol4m=7~`pj;0^ha9fP!Z zyNLWRy@-}dePJMFPA3-^w?-m2pUK0wDzk)(9*#juMeRYBvgjtHEFb+^2funBeJAh8 zclPt%r~7xK)jO7)58`##FqlLXnOShEsbuM0ua_F`PW)4hb_!D-oxO$S|L9nq$_QlM zVuKb?=l3k3X8Q}EUm3>8|4IIZZ8-tLkp(Hw;H!cakEdz4JV~MyWaGBjXlr8(BE`S+ zSP7BP-1DUR58b*-*-&$JVjo?njytWu1kf2KMtzqkR>=AP3iLC<pc9k5J?+qwIB}}u zCgL6Qv0uU9S^xf#+$>gADIYm2=G}907_w|vBpa@Os9Ca{?sS*AmDte$zt}Y&2LZWw zb*rSS2A-E(dCnjW*6tyQf&+aV-+0Kct=I46rot`L`?gkk=bxA*^wpq$vBac$&%<hi z`~=YWT=FU>cHYp(CbL`*r>woHk&{ro<!Qm6Apf)8yxWYN1MeC!_GC<6=c2!=k(Q!K z8%@VsIeNU?2jQxody`PUNA(k+32&;>!dWA8ypa%foQq^jhU-Ml*!H@J6XtiPfgds7 zWsor!F@nnC_>h^Ll+#&AE9)3znrhl1NP~thDjsT;rNC+YBvJ?{L>x2-*4~4}dB@!v zia1QTAwQy;Yp>}P&qXG9fU#+V;en*ttU)o0-Jn&`T<neYuV>I16G&HtU^dbWZIs*1 z1vqlI(|prLZh-7fo7Y6iV=$VO>kJ{Mj!R(T0hDQb7WWvqFB>36nA<_ED6Y;JCu{dO z{hR?G*iidS8J+FLj~;N-&rM4N)ESo65pSo|ghw&8X`!t#lQ`EOVgOVD7?JLA9}fkP z7qDAc|2c!6gG*DK4XyMZo)?Hp*o^$adTgrAp-Gn+&d+zk<L7a}yiqL5Z$_%wGY{}A zc4;VCiwrs=x;pu6k5vL@Kt;X<R+H;x5C9Qm_?fUG*lD*8)&{-})C>hr){js1N1-|y zS7X)~rVRL{%Bd@{Bp4l`DyOBiy)LZ0XB&tqA9)l9%E60(l9>2N&^9$<>|sn$70aFw zWiZmd$}vbTb5nN%frl^P#h^0X)pM9<0wCUIg&B+JA?+_fSJG%{X#@AE3WNWbG(RPo z{-IOgkbG=+I+OI@n}9&Krdh=(LA}cgRTZm}g^70~<RHtz6klQHI}Uqg5pAL?xLMT* zbXG<|#>G#rKc%sjMPhi&A`Vnb&qLHX%l&OcxNQWV<TSq6xw++}I(xCEW@~{9Kjy$L z`^^cpwMCDQp%>vzA`a>J->`jOL!=I{vx7M#AXUiFJkWWP+&oRH!q*^N@WP-`7GO0R zU}vnM?T2N73^20uf=Vj)%)xmrxkI~RkE8Aa5|&Dpl4md(j#8=gxooqnD>DybjNWcc zs5eerYTQJCZT}a)8Af{@)y#e#(m!Tk%bX@LIs^<g?am9qZaziEwy<S!qt&(zU#^q0 zZ^nL8BVw_~SI?OoRQ&{U%=^ipw-=?FvyB)ixZ_wG+gt}fS1B!_#TLH&!wNS0Ms~A| zz?{r@&=(#<Jj(!`_EWfz41rUO^{#T*_4REC8o$*ChWr~}CfI7A%Qan+f$dIr6ah?K z$Dt`9Se!?MHgLM@|B^4LLB){fv-v`H+6k|<BQctkVBgmJ^gcE`X02LXf$l2j3<2~+ zAVZAfPb3?6l2`(!>t(A_JYhq3g-qwTmr077xKYc7F2iavonC1~Oc;Y-T9q6gBoQYM z<JFd$I19Az-~H}yB}b|9R&;DXMoFy+dync7&@JJ0GUg)Z;X8r!Zd)6wxi<JR%IbR0 zlORbmbxn-I=GX$Yf-O&b)-kMb*uS;G-QaQHT3c@3P|y#?e#g7`^(PhoY-rRU&J>%Q zCsX2`tOP;J;ICRHuAxtFberV>q-2CQh5uDL1cI{mYZw;BS%DYnK|?UmhVPRr{H2IS zn4>)#{K*G<lCM|Fvp!R+%@8+b`ysVbNdD4%y5>k!nsuNT-IB0rjB6yJ$(FX>F!ZuZ zU?NqSi!@6BSwz?uI+FZS(Chb8&^^f-6M_TZn15`)ua&44*lOYgE$c2GPXvw!>WjC{ z&Pqkha0lke66~PtFsCWE!&sLU4qTl%MR6!tqhsU1{H@jHyItTv>eaTv3m$4#g)A1^ z!Kx3ThFCPuJ`CQl0D+LQr5@XbLJ%so$3L_mLl|#RD;K9LPewa+5Cirbmz`j#+S@x; zy&6ay>W#W1JE8~|#H}ef3=ck>4unPZ_TTtJxq_!t6JgJ-SU?Kf4|~S34llwTrTBk3 zw0{=;r@adnpFFIb<PKU?KoQ$LachGfi3B`ZX5aT|?>CidZhPeo`s8co_N5KCY$o6{ z05NvO_1}VYNF6m`UzmHtyHUov-_$i^r{g1v{J<R0foiSvznA?<Ls3HB(wsVj!QyJH z`X-Grs6Jql3tkruUGRWJ)D(>Y;o$+ILmU*3He815^FYfl&%E5;t&C621wCHKzgNFy z9@9_4oI4+0R0#P$_PIUuVge^4xoDwB(UZhF@REhVppr3%X(i7P&?_C6FY#n$>mmF> zFemSa>^)s6P_R;0P>{RUST~OL*F(9>wD_`2gecYHJmWLFt2T>SziHNous%KEv4tX; z(e{TVlh(lbhXR3xI|Q8h`db@Afr)xu-`iZ;7cuZgmG{>$CVhAdL@U#V)1D|4hoEFZ zy8Imu%*(3in+KJ@;{C11^qawzBs0QE9Y1)ZgLOo{Rt)@rwP!y(^&QH*4V!vou)@i- z9xV1ZTU}%>(B;ziOD1iJal4O;Z*Q;`=4?QfHU);!Iu@{ULN`DVAV>`1+mfvE2Cw=~ z8nr-zD*FcYfc@!@$^$co_L9efOX}-wI4&JtaPQ0>5DKOg#t!j%SVfoQN4sl2tKeVx zU`l6gl4C8$5et!5%cf7w*LSetuYcNj+yB{Hx<9n<f|Y%zJD-BzA?!agDisH6(HLU& zu6S_;TKKje)c?^RNCN-T=ncO1RR_A0_55K3e?*=Qck#t>`RV02!oKXb)>YA&$b`{u z*C3zB1V?mv3FUFIR1MgIR__W3IkwMrZaQK(64vo-mF>a{*Tdq_<`XOfkhxAE?4l^7 zYBk1Gr})|*z~&ot!7;miZ26#XPt(@YKPQt>Qs$^gm=0XS-n)49H1vKI-N|RUTNwsm z><s0dXK<Jtrol){`6L}I?YXhTHpF?@AN#d`;IlS*{X&_Z?_rR#7WsDhuv#CL5N`*X znVVL2HDEIUNh7FATgjvca|IMhxaD`tPVl%qybeDYP%9GfzPc4v>O?dP8yo3W?uzfV zp1zLPb&fH3fHe4xc7(M}V%X_e*tr-%(+64cXDW@45v&Uw{B}5!c1>^6k4~A><8UN+ z1X_Q($l}CTf`q*|=yg0XWyF~rI`;1X#g>FvPLBftF8TkfX&XynI+hTUV$=Bh43*>i zWeL4?yw=&z2}Xa|<Iq{dVL&5Lv|sni%!Xke>7b;TVE<t+T-_=es@%m)dkQvq9+Dkf z;a0471L1teJ7_9%BWc?;t8fN;tkg7fT2y}htLL1o`fVL+yberdL%I!0w5`y>qah=S zpB7wVG?RC6T|&RZy2`7oa*Zw7i9BNEPn%kcC-hw{f5G##{}y7w#g<=52Y$`j^I<!y z)#ToI(LUO?NK6+YQCKHX+UIVLD`~02Z?2n)nk2qE4nerT(hGNugI!*em1nJFbvj7z z9j|YkK0dts{qO=WFV;uPh>!t!zhBl6kG0>}7=W#|bCL9J*$^T|)Uo@9Ho><nQPvK( z<7PVm@XVyo{1v0Jos*`!Y~kKg{whap+%;#mGN%VuVU&VomrA{hz^Uv5->MS)P@76& z(*yCnH{jH|Nq=ruUy(qGJcOKgW+AI>8S(ZFkC~)c2hj~)HRk!W%Ku8_2&g{-<j8!> z46Kb^H!lE_Gl9<J>FII;&=Fe3De)vKCAV(zNe;SOgR}T_DYX{DzIKlmi09ymA@jeM zcsPeFm;Ys?8Exd@o4QwRrNlIm2?c?G<qpPgqQjT)5yO#d<)^y+vAEM*$JnsFqKDUs zl>RJvAoB^3;|xxps_=1ryw+!E@4D$FsW<Px?B$RSJ2y|^dc)iBVT0PP+Ur>AS@DRp zzWaHXf<-+2cL&QM^D;hn*-FtT3gcQ(DBm18Ft21m1G{gbeg9Xj&?|iADtKNlMf-h) zopA*U!R@}V7s>@H=aTj+Z7THKMY17D<xQvDQBi1@*gkWTCa=5vZ}AXQmGBaNeSun| zQN;7PnT=n5)Y^;17C$6Lw(81viONwsAeT-_*PpCv=vC<D6pg`4)d2T8{D&2GY@MTA z&U@4S_a_i*%C`35{y?N;yVz96nY`s4H#6OGq(#Q=YS5BO&1&MvwymR}l>~;{x#Ua4 z3*|tVc^>_G7-><lYWw_n)om&{pGD8$rz|k=f?CnDp!R8<5$DK?SU)p)6A)0%5n%`e zcbr;rGKuc6CJ7_84zqcZ*7)ut7R;NqMNYLJ(7auntU%AF7XbLrp$@erCXkS(uFgLj zS-TVwzmsR(bglSWqu20dT%+OuCc3HPX5uAH?1;h@!8%}<^Ch5hVlFZ;T3V(@;4uiv z*ixOGr<oiPl_ScRI`n6N$L_!^jTq)<Z-GGnYaZ)Lv(~8f&8fw?@i9V!#Uc1DGx&$R zrkt3j3JgFZII;Q}k%tz|KEhE<wuwYW2!gA;3kI?hoH-MM?Z`d@gbnLe=x08xPoB1l zTnw^Huh<TX0lW9QqWOB9mDU}W13cNE<==0wYkE+;U%in{aMVi86bTFF2`A=V;-1M{ z8Q9K^0()D?J_+Bvh{C6U5T50WK}{z$*p@D86mIE^-h$iHY5Jjj{nx)aMxIg_7HB+^ z+B`VJc4>z0kg6W}5++F^ICtrB;x||HFgOE5w>QY8O9e-e`^mX~)(4%$bDQKt+^8B~ zKqx<vx#mFXW_>pPvxETg^zK)aGrB#$e_u);;Kh1-h;_tHJyQJS)}ge*;g(DNnnlh~ z40KPpC?wUd)pO*0f+&s~2(Si3T}>1Al9A?oP#6r{v-$&|^QBS!w0%j~0G+{Wsbwgd zTb)cc!*SH#<S=^?|9isS&1p!|{@}%GFj#^DbolG=s;b%Yup1x~e6J0f=|Is-*T8Fo zDGlnc&SwIc^u;IHRGOL8mIsgk^(zU%ka1o}7EKGSW}V>`JN~YusbuyE=q<~pLrmoR zZZX>fI~q$z5+(DY!M@2-)-Y|<z~I3pt?{i9KRmBr^VbXQ8tAgt$zGtDiTh*#J09ey zSxV|=qapQNd$@U{G~Mv1{}90&eFp(-RTqaW<_mn@NFIUG*(Fb>(wm{gCFNfU$d0kP z=v00Lz5d`v5tod26tFQlC|~gh-KJH5r(y;>E!GyHsd05dn>Cx7z=r3udS+E<V^7-d z^WsOxJ_A)YIVv(dEm@f)*x`<}r+~LnW(U;3^ILw^QrBDBI#PFFYx$b9Pn@cTZcJIr zW&$4TgZ);Au%HMgwVv3wla*kFLbUVLMK*FC9poQU#=t#?VbU><n}rLAhFm_F<dLR( zW@RojLTB-WXjK3Xf1@fRrq4a7r1F2K2(Odx9ybvHxMsKRDE^{BYqnI6S{$%QyBRIB z^wU_;`<dR<m_^yc=<<33sY4Q9w&MLieEC!(Ak;*ctncn9gFS$ZVC9J8SZUdoVEHB( z+tL{={WHXb7_8X&Uf$D+2j6B6YoN|dY@w)-q5q@mDJkaET?2#XYxP<C0?ZlN`bkMB zT-ig2wwbJ#JYeL3c;WyrfmNPMO4++%#kby>|L1cB(Q3Y(Z|yxu7P#UFF^L9UeXFhr zU|c%r^+q=lMZ$qUV2A0=7%abTA2(0vuEg#FbYnD{=BA!AbhwG++x}99j6$JyAcEoq zb`x*)bT}1+7+#(n^8Rj8cNkHm!=vNm_%Jqc(=pbc5a$p~Vk-I>Q9Bx77pVpA1w~YT zD@CWAf8UVV3-;<jFAQ5NwLv6^1MOM4t$1|Xzyr0?T#}pnVP4Jq3N1cBd`H47CPV6= zk~C5PbI>1jx?2V4WDTnyrAJ1+J)L{TMAZnpKxM6Zh5wK(wva-qFjY@i68t7`JbRtn zZC|;(xG%8J1lEu8L9piGH5OU=?Rjqnxj*PO>Xyu#Z+r>k59Gas_Xxydv{c%%f-PFv z)|bg^A;fQsA9g@B*sOxL<etHz8T)eiHCm?Gt&W5-jAZL|oi#o&|BYoV_|nw@d*3$y z9LI$@{=ogqS{n%@9XUpJpb*3LI9H)IfrsY}KYC;C#>JF;B%@OW6=<3OK<(N6?5_5P zb>R3Py2uE7zynYv0&lDZdXOs>Bn+<xE(_Mt(lqk{XNsd&n6h<(`a{OcFqT4B0#Ibr zLK=jwzj4jL3T6$B%D&^sC2x+PR1YYv3Y`>mQMw*0#eoHg;tsi+K1##>Skt5-6yO2= zb8?JC9BNdzIB%T^YGP4YznSQ~mffRAQlUc;K_)eZpk&_78XCv}WqAjVG^Gy6-~T3+ zH4}@+rxF#mtmopjUQ4v}6NnaxD9)q7xO5r)8S1tc7y0IOolE<l&DP`kPcXQF=X6}% z(|CH*oVi1L{vjQ^9HrwqEgoqwxsC)>^umpG=hRrJs{;P!3c!d+*skAP+b3`XK3k8R zRI;y1Ec07%tNZEAIf{$7F1>npOmNvc3on;t(pu5jB|&ncwuS?Ce<?)2vQHywQ@%{0 zR<pBXkleJy>?&Gbw;U7UJIMg=0K}qcy7<3zI~*;2d@zi%TVJ-puXZG5Lx8t3fuS#? zn*(n>w~4a*nB8pG2BRd6A00QPX7nBu^p*3;H3=u8<JXB=)~nNo?j^$v&S;U&nO5OU zAj!R5_7pgZYLh7qbg}b9pJ)T*NYcePTH1-^6Yr?>GZXS~S5ju4i)=m618eqg&)_nw zc=%W^ByQ9AkH;Y8n{QO1L16BKr#-G!ah3sjCE*_|QGZGXiXRdFyNM>(ob|gAOSu3+ zxvqykslZm>92K24B7kpsY;Iv-#v20|c5*Tj%Qka)yn|#>-@Rje+jF@DuB8=-(hSy& zQJ$uHFL<0Ulase1)_|sV=NO&p+S$=DQ8h(k*eKQLBfm9Y!`rv~i#_xhF)t+aRUpp- z7lA+>+dMfp|7;$<3@uxEZVQG|yN-vp;k6%ct0_gy!w62ZIp;?`^<mr<<pt?|9%kHb zj{=3$xT*dm<)dw+6m=|Z{YfJp5$L5{Q0vBKD%+qxHZXyowcGK2g<3W{Dq$BQN&E~~ zZf!J=_ieZVn?*czD#nB7mYvxU;4NeTaGc{^y4IfmLSLjqs?G*N2gWVdq!8<iVr0mB z_)XsSawYfhmNhKqOav7wEAL}Hi1d>Hu=)r9$<UH9qX)K&{9~=i8yJ~+=#VZq2-y9| z|M1@|fOd*M*5A4!KD0tCA6HYm@j)gVR8mhYRP0~AGCzBa8xmaorzu-n{x)*?T|4TQ z`{kTKtyq=7`b5yD0*euF4w5CS6m?XIJxEyihc_=1n<L~AYp6~%@995TR83~mzF)R2 zhY_(l@%RwNFh?&|=|fu$Sm;|z-{73(PM2K;XV=nY%^?A^8+rv&uB_=;!#R(Q80pG5 z%$6-R`qDw5hW$_$*t)6A?vRG>VZkLhy}(<{vA@y#A{{RsI>c%@>0kaL`-^5K(8_}C zXInZnnyQo*Dcv(z3)O!>d?v@+9V~!BcKj&C-uy><aece%UxVrElI|ChFk;y-rGj}s zSp@ZxXl;J3;Rc*Z<Yage33o;*Q!lOPSP^+o4{$DaCRy?E(?cK3r`Zq0AjeDSlsCne zHMgT+L~Lki^&dST0fqT$I-wGokShI%;}XBM2Co?FUPtH|eMjHC@Rw1pYDTojod2GT z9$#i&+|MXXye*OkEvbmouiK*Q2kmlomQQ1$QtbN%d3XnwrsFQcc75$pH9~VJTJ8Z_ zBC*zR!vQ9ZlA7y~qS_56gMTgSMxHr6Neav&PUw4Xukkb8W7EDrwjco51V0u;&%@-O zlmdzOmcE&2V7_ku;8G1Jq5es>jJ$o)Er6WS7<VCxXtY7|TL;*Y4<%*-UwhCg3g}hU z<A0QYn90i>4u(H<gTvFHqE&LK!;x_9=TNCuDeJ~Va!^*!U7KiodjyzIyk2y727sCV zUfXryw4Uv&Kz#@J?^gS9BoDCmxCEoou?uBrw}X^5rRh+GyQZCID{&5L4?`y1we+^h zEMlkc!Z(j_7;&rP`vIFCEY{3#fI;tMdPcw4As@g3x;YR`z9;A6FM<R?t5+y43!a$n zpncW+;ON*fB|&ZbM4cD>ZYbIP82~Wq)YKrq$R7v{jxT@yxVGH{54UQ_p!^;H9ayOo zx@*6@ySF90^}3VF+4}3qDJa%7Wsu`;k{}1U84k-tl6TYBJOnq=%b&z$D**nO^@=36 zXM<f_0yp5#lLP$Phi(di(-@%&UoHUr3OY&9S0Vo>V3A>u&N}Dg4g&0-^8bk+$%cd0 zM4ICiWJg_8%GF)xLv+og74Nv$lRf0@J#3A-pru}i!HDA$+?fo5fk}P!8Ys{`!{Bqd zYgS|9$-!eW-e8SFiLiGbN=e!KJ40?)Zsm^M04v!@Qi3g+*aM2r#tx&f>Qiu!`30>+ zCxEv0z%PM?jQ@9wNPfB^LHRC*M&eCei}fYv$y9UGy$>A`7W_34jY+NAHWB~zK%b|5 z|7MoQf}lmUg~pha$1ztgh1R!(w2|cm@hq|jIhQ1odk-QRdEBbAkzcavJOb_Y6~?@2 zj)`DMaHCcEi|3*QmrDZj=d+NZ>~tFfJWRWBzC1^#oMsoYgn1}(II8EZs$EnKQ}wh_ zwiMUsM_Lu2#<?8umN_Lw!M08ijzGi)_okBHlNDBdzQ)Hf8@K(p_-U#6g7Y`Yok($D z21hN|#xundwA-V!RDQ0(Fer7{)?d!DG?^T^LlB;RX6C{Guctvoqg5JD0*7fM?=9e* zz*OCXK$Ib{*oxmFcaB#(O?YNW*Dy<hlzNfjM_FDOMdhy0s(mOZ_c`v1<WK1muMr6d zC1YWOXWI5AY`x^FpJUwE{rjGtfkN9}yO!f9$H*iZ6e%b~4k5?^Xm+V5%DpIy73N&b zdb-ivsysp|wI0HuIsx0Z#M{=(K<8Ufodr;l+OPLP=lXdTKZ50^qxdg&AkRAt=BLt* zZ`Oq*^g|V_eRv&T=S>?}8f1NgPqdS(_AhT}6LA@Zj|q7H<b{V=q$@rPyE&P8e5^J@ zSAov>c8id<r!jYIrXvBGXwsLf=sIK&TNFk)=Y}a1c`H(YS`)F{p{VO$f$&%6HjE35 ziKyLTO*9vrlvx()#u2Y(Y0va9FkNK0pj}6@3We3O4_d~(#XZ30H&^J2i5;5{t;OLX zZ2_cD3IlU(J$T>4{GhRX=^&J$1(VYggqi27Ksos|2Agd2LxoxC?GKH6U_5Xe!39Vs zBy9{rt`=;G9D6vSQqNbtS$oc7ChbjUAOv3hL+}saYV_Lwnx14a6M1x=D?B`G`8v-R zt0ij5uQb_=t>s8ul^yq@eHX}rf#w^iPdh=kGe_6+Wl}(WmZ0kH0HyN)LP_krp98xm zV6_OG%4a$Y<Iz9-1bQa6`$_ocXZ>28rz!IU31JcK#3$y>zPfZm|39^Tpty5EFZd|C zWl)kS>XZ#9jE2=1roa_!eO;i{f9sS(05bwHzzhr;sqKWxRNXjq?6Hx=wU0MRyO78$ z6-zcME_J^LD5Xj|fI23TOzuCR!;#NbDPG0f#_MQTq`qWtpjE4OPU&glX00lH#6TH> z45jT80>{Ts^P#VOzg)t0V9+3GULx}XiY#7axQrut?w~ibHl6coT_uAlJLLV5dedvR zKr?|huM<-}2@fi4klHBgp7=e0#z-jTFKcKJ<{YU;&L`0bi%N~D5<Dkdxa;B!r||W# zwymmm&6Qph8zZp*IWFtW7Qpo_G?e;%ZLe?#*_G2ylcBWj!s$CUNWopk_0f$18$Jb- zIB~L`KtV-=&*{Rm534E8lIYECSGiQh^E+I)ejJay8428&zIQz2=vH^+{z0%MNvQoO z3uvL3W&F9kpb{_4gC9#O0|K_{YqWkQ&2VzU9x2-3$b5#_=X~=r4*7i6V<}nlWcbT~ ztbKRvGP&@oDP;S#USaA>QL?2*wgPpwyx+ml_mEdSnJ4lC?`kwVs$a#Ll$)|Ibjg@P zuU2CxV+!oxMUObVBr{cCZw~Ek(ZX=NX$vsm26z`w89^FId3VWLlX=_|*E>UL^<QLc z7#lz-3{dk1WNel8E=6YT&Lwl>B^7jb1sARkRCs1EyaB(yyl?O4d_Tdnv7Orx`N_Zp zb#xo+`UCq7N^N0x7>GWO2eZ5>^2ztG@@>Zf^b~5${2Q5#a?Y`{7Q^gZ%kVf<_KIeJ z8H#=<0&}QDk<ne4!X#*Jbz|cKBSRxh<-)AIr`SF7ggWI9;8_?o1tmDr?7((iI7d1R zin}_@oqqJO8W*zt6;0DL?b*-dQisfIyWT2rFA0y_AcDC1b`T;TT7*>d9)M&c*>VK< z!|h>5*81<^`ZsJm8m5We_#DWS5|faje=5)jRH7sLHkKtip>S3q|5J*{4vz%My!|)i zVVE2_DYgA55I6;cj@L4W)W$ggQ{Qw{&q6iDe<5gYU+W<LBKuyPU>AXHa5Smf8BS&^ z59|S*tu8?mHnk7Y$^||~4zuu4kbJi{>q=9cFtupQdb6A7^3`jLI1Hc%jx6wh8#_5E zr`7JNF-i4@6cnVo0b$5+>~CU&3$`yAs)iV7^-6XY5f&)$<+{zJwqi`YW>!Kvw%Jg^ zt;W^!Ua|K{J(DrY)xR9^`_$D4;f-uwUsw8Y`F8Pf=6voriV|Izu#vnUvET9b69F#h zxw2nXpM-)Ntcfyd1WG$RM}y@xxQGKrTJa~!<$;qH>?R@2(QIU*4L{b*(*9)TZgS>C z(Z=``u4jDnDORKrns)o$DDZTlU!ktYD61FAx+yNVW3wD%BVsV#eJxukeVvlhsgt4T zrKu3DUhGPZSOq+w8l82#_GCyPW?piLiLg*P+!(QSEticg#u?Ze`CWLOrbGj;1^8jV z>H3*EjGFpy5($^79kbyEJHrM;9aUy@e5awm5Sbkyto0Xip$N@dZSw>5ZihDG{H)|e zsQ_72GfYV^G-5w-h|=d$O1rpFd7FX08#l_r)AE=aMO5^yfXkuSS}Hf_|Ktx$vG0FJ zSS-8efkcSrj+L;ekzD&=D~tDU><>3zSw(GeC{AWQ4t?d!pJ1|*x~65>jLSxqYNRZ7 zk!$lr4^^`-e&0l-@W;^ESj(2wTPOS|X4y)0xpYg3@J0u+c8%|`@}e{GFSjbD&BStC z<Hcvea?qEYes0C8?c=7F#*8;L;%cJyK0=o$*uLNg2meIwqa8npEHtlRY$9{AQ<z#I zpzQuYo9{!1M>FFP$ILRL$8OXCyr}UbY{@FUuuBEW6EtuFxvY@>jbFO2B-rI5@tmA& zUAH0STZq}d70{fd$iHQRPP+I7&fwS5+EV^uOcMYMVxwyfr0alvdt9Q!_b;d;aexzV Bew_dS literal 0 HcmV?d00001 diff --git a/static/images/docs/products/databases/postgresql/dark/settings-network.avif b/static/images/docs/products/databases/postgresql/dark/settings-network.avif new file mode 100644 index 0000000000000000000000000000000000000000..4035fd641d53e2de135ee1eadfead07d0e6e967b GIT binary patch literal 32262 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�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 Rr~l*-F%vgim`55-@f+;BpeFzT literal 0 HcmV?d00001 diff --git a/static/images/docs/products/databases/postgresql/dark/settings-pitr.avif b/static/images/docs/products/databases/postgresql/dark/settings-pitr.avif new file mode 100644 index 0000000000000000000000000000000000000000..f8dec97f72aaaa13858797f5447e050d626bb499 GIT binary patch literal 33959 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 EfX49EXaE2J literal 0 HcmV?d00001 diff --git a/static/images/docs/products/databases/postgresql/dark/settings.avif b/static/images/docs/products/databases/postgresql/dark/settings.avif new file mode 100644 index 0000000000000000000000000000000000000000..3f1cb84f669d7ec17658ca5e71162f1827686d07 GIT binary patch literal 34735 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 D@jf}Q literal 0 HcmV?d00001 diff --git a/static/images/docs/products/databases/postgresql/dark/sql-editor.avif b/static/images/docs/products/databases/postgresql/dark/sql-editor.avif new file mode 100644 index 0000000000000000000000000000000000000000..95831392f812d41f268b8a6508bc48c286db750a GIT binary patch literal 26576 zcmXuKQ?M}14kfy6``fl{+qP}nwr$(CZQHhO@B5#*GwJHAtkkONJakna(hUFrfNkpR zVQ=7SVG8h{*;tq|{4ch#F!&!|wJ~uv_+S1%BQQ6%cKrWC004UnBj^7Y|38GYw{W)k zKLqeUPiSFnXY@ZN%ntzg-};|@{$B(zUHy*{Sy<TqpF{so7WF@30`x!Ce_8`qdWQdn zsuuQ+_WvQfg}ss8e+XmX${-X#@_%F~7Ebmi{}TZKfd03E7XEVx_7?6I|H}YFKtTKl zXcqQ1|F8c4iU1A(0tNsu-L)|`a7F@vg5t0=`zaU%!i2?V9G(Fb6QBk_;0KWh&?5SP zVX0Lp>9=Q`7)knbn18132`8jjiBA;dtC8DtI;+ib6_8f<sDQLUV-_>R(l!t5xoaDd zhH9xaM>2rE0c;8;k9Vn4`<q)p={<FLqaCv6;qo5A8Yzi<Z-t}Ru`qmUpP0AK(rZ1} z`u2r~SX!nj?f%7DdB*n?Dnig~r*iVOFT@4)aB(XT@nrOb^La|4qT0EtpHNBgqU>Mx z$`6Q2czR=e{xmJ81^Q`vT5E?ud$FGmn$xZ!vm|2ad-GD$KVap%{S+;_3w_&A&-2&7 zITMvf4)CZ^XndWn$k?}`_Q(NF^2^n6gL4jp!F!@_^{ZwZ%ScI|5R=JT_dbT!JO$n# z3Zi&Aq%cAHU0~A-Q2RG8)E{o$Zm>mhBryjtZ$sIi2$l5*9=BfYlO4_Cj(6zhWFK;7 zf<ITZ9=?P=ZOY3CF)Og1VKctWq^&czYC5`nANzYnC|aB*CE>oAp;@Ujpbat>=5*ZS zNSCFQ^GaF2T$~}~{>J477QZVry00Q-Z|!1zGr~1}@^`0FjGpA#yK{tJ#H$vIQ?O~O z{j*nuS5`>CdmbBS_xeSXM5j;sF{Z)h3BU=;+i@RR#o>2sVo7u?qE1>MX@}nH9ju1* zb1Qt!%&s0)fiTd&L^I@184D!<J7KbTpYD}Z`*kMSU4?ZFwvtkb*B!yhs}5vKZYa;# z7Xdyf8p;x@&179M?ooVor79k?n)P=PXBneytT`I`Duqu1*?!6Xp@yzdt{Vk|DU$oA zLsURz^pordM&WxW13!N9DQ)j4b9Gj)IoZR7#T|GO59D~Y{^7hc{#!9(@2dI92Gb>S zkGCFHUZr{tuXCQE(C2+m`f=M@-iQ2SkNOpd^iefwKgm03Q7G9w?Rg7yq8aJw%0qkT z6sFMpcIgQXqszCH!h#0r8~&1Ajc2N+lI@pp<)b0IK}0MHSMjhsY{D5n*`gWt=Al48 zN5*$pzLBRpVPu|QQc<|`K0<7S2jBN^0jYKkgyNGx&#B(7e9MbWxbar=Ly#K)uzNV^ z*`9CnmeUsRqXbcd226R}Y?{(Seaizqx^}>**QJ1yd<<ek_SlH^2q!bwGi~ReZ-c9i z8uamgACHGm_@G3>tt4fLsaWKZ1A7H48KaHOlpm1+3arAhhP&)YU7jCPpvIqz$WYgU zE95;KN~>^(kh2Q9x`F22Y9sDkon^wndaCAR*dU|VQ!==7jJQsz_Q!Vs_QUEmv(j)I zV|}W$Zkhbj-jqKxFjOP2&bDQ5Ztf2WB0v`e(}z+;(kmx0>!8bz*iVO@?Q&DfG`26E zX!icjn+kp~k-xRsDb&%Z_P`xDRK$uK9Uh427?p-$*X(}1-0<{X#|0*kQ3O%Q5-N-a z^F!&fWb@mjfI^`882<wMti<kQMx5Oh6TvJzW-Ohq$@259b`h%A4y7I(U*sNI6d6=d zGp5h_IHdd`xH1T>dzw!gV^f_>>z(GuwmNO20NJw#c%^>Pqr&G}#nY3<$$2`t#s;R1 zNH@)j-j%iy@9%e!MSXxZkSTc@8MenLq-h&d?W;*zIBti_7A}XH$+&!OsyDi5cX?vz z(Fz;Dm#zewDtS)y#LO)LC6@tu2DkT!bCSK-+w5}zsDQ(~!41^+GVFQA5d^1RH~i2U zRN#BhOagF?rhnqT6hMfhh;qk@_8tZT<0b^afhyBQa*v(_Y`?)1Vk57#r6~ZECV*;B zJh&9%im7{CoubW%6jFyHWoVSM860Y>llt2HJO##jNv9@2qUkQ2N_m^3&?;2KX_)RH zuWk2lWBp2n;l!r++_05uO8B2g^lGpNiL}90tCO;@%eiX@EI>bQg4u8g`wb~JE1%8X z6cQ8#o5B;^$yfeE*ihg|`<;Snt2UDAc6V?4gYf?8G(Ej$FBe5sebd0-NJYtEd%c;& zbM@G62t0;kR|^i%pi*c7&|nU`z6)^jB&4;Q#bT@_{E)0hBaR7S+}73|khqUfYU0dk zj&n$vE53HK`5>^E^^OF?5Q}!N?DjqTOf1}XsEyv}G43mj$#pCm3y<m+8ByzYlTE1u z-waY3!^z0(Dd`5>Cah8&$Y~{Mx^DmSkF?78*DIDWJy&);qWi<rvNl+|n51SbJJMw6 z&Gb?zegbmIPk=dFP~ByZ4>u$fTE+ask5KtCYg@9ywEO3Th68sXA701a)lo6RmTsJ4 z<Mtm&V`yl>Km$~FehRY_<$-rgKuMww5G96t5%KX&-<$h6HMUKfJ7Q;{=o#8*<u)08 zk{c&+#A6mX;)1U2d3&9-O<_ar=*oq1p6gIhvYmIN*gd=90KdS}!XZRX;@yBaUY)3% z7>)O+#e}m8*iM>%_3?~A{l@dmI>?3#$Z9zGYQc9#<QexAs!(^pV?liST|lOh_T`nW z^bAUGH_tBo4dytEb8KO=bRkq1s^{k*67&O7n<X?VuVHQYj>VYi6AgTDyDQH^CpEGp zdWl&txC6i>ZR^I7<TC*_h^PWUo|69~4!&$FoPhi9<#VSLf2NJ4U?No`64cRtcvhvV zV_Qs#TX*WVB1UB(I1-_M%D?67tiP=<nlBF=0&=Kq%DP{PV@<V5gT$j&<K{CH!)S=4 zObfKT&fYBVS$_7H6b<2CBgA#KqoW)DM&>JXRI{BbY+co@#iJ;yt8g((@4)(2--D4< zQd!I1L*2&waKE03C<u}FPx6pi=`P~b{f<@*Z1HII+ubDTi7ypld_x-|ze}nrFQ}eS zT~7eE8Z~aRPsbbz-1&M+VVyY8=KAN9Cw5vCKwvY9Wt&&}IXjy@ochK2{wB0I>>E>A zyZ~=M^>V~-uq6W0!dZgK!N+(Gq0^MEb%|5`itW4FP(idlXA)J+El`rrq8*3Y3WE|5 z)P<Lggbw|`<uS$WPHG8Je?r7oV?(NSb}8Ii8G?Idtuz927^x%MZ&7H3tZi_lBu|f} z5^d}ernk^DsANdR9duKLW^XTfREjMKL}ZHPt4}5WjeG3rl|eyYw12Lm8YYMsAt7wx zr#_WAa*V{Yc&GIOn}OC8Hhg=HY*ZJuDwDOlPS68sI&rb5l+2@s-=11t;aj2Q_$S(X zrBN=P7`Q5dDdi{_MYw82EM+TlklE2>a|arzjo+pz8AkaH4>>|@-HdB|LC5NjZ0*qH z+PaPbMHMNFQ>B9w{646Q8J~Ub?IPY~(i<~2K#%F)wkhxi|CDSdj)rnxqbjkVC+?-y zGYRbJvSiUuk4%q~5-TTnIE3PkIuI8GU%84w2NY@}up&V?q67ygxO?PV(Ck}2mMi|f z>y>b5|JUq7{m<2S`nHZA`!R@tgQaSYySq+Mc~5qaQkwIu>bX8#rwKE=6C***Q4xP8 z`1Txr(A30*`)N)LxnpNatW&x55vw?QBLf#T7bZC$P|V%kJG&T0f0Bw`7flFUoD-<^ z)qbg08BJ#o>Ce(XU-ox-FedkqTxykJ)#5nhkZyjbFl3ljVHliU<8<wLYoZnrihJ#5 z`Mv9(cu`OB!1#lfZ8!=zO{|0)0jWI`@WxP8BgD8;agj>|SV>js{;|ckZ8o|2?B}%c zdy>WHgcc#slj*Z=?HzXt*-T2=L@F<e5aE+66b&qklw3v<tT52Ku!NrqBt2@AU($Ys z+HEY@Y+oe=_jhir4MF7g$Vfx!(=XfEx(Uv^G@P$GV1P8|XD2+<ihLY8rUo_FVo1zj z4hM^(UZfw)F)X5HD(Ig<3tst^!Eu8g26#UBmZsGBvSP6LVVngwD2ipbwoqA~McKD! zuCTE-9<8-XM%n%*CS`t5N*xh(4&>F9Dn|t?=;Bi;mxtnRg@H2csOA-+NMm7N_hUnO z!8&$^zD6=oAHo=fea|Hu^fUqed;>qGtdaHH0fDaDP+$@85sN!QfoCSjv{grjlDm{} zcz1emZrD2NAooCPW=G$m?1NJ!>h)J+moGB|p1P6E$ph?>(?KfAvM+jK#+@HU9_<?k z*~5Yd8i{*E%R3sBC9Ix>v^e1x{sY;V2*as|CJTbB>@H_bbM2bjdi;`;+#X41L$9}P zV>{ex)ZL8Hp937~>OIguLa;s}4<m~ZrPh;5!U(|$xAFwwLy{_Ib$D)AI<aA0z2xj@ zCg*nlydN%oA8m&7zRPZ)ljx(-IIPYi2Ll$FL<3oku*6imZJ?q-4qXy7!FxEk6=G{e zTIRC%HJ4fX3)1aEEqWz#N${ZJc|(FTBfb9>3>+pgZ_$>OS-$-}P0dG~OMXp6t&ZO} zn&q#00SZeb><jS>wbx8Vx%o^qjKt)r<-vWcR8C2sO-DQR4SjyA%^}pQ8Epr(Q~4=i zx9>|cOw!dNvsIHqi%2my)^C->ch;OD(ri)weoGC*G_Wvzdq2~#x*P^B_gXe27nkVL zvWjud+tNzcYPfzMcYpEZ#n6UVS#Ts;uiphtK6W@Q4wPed<Vn%}P+69Q-Jd;*y-!|8 zJw8RVi3MGVw;lbmM!x?=jkn~oxQ8QrQ}SP7d6HE?0bsL+0Jqb%v~>youW_#0XnGoV zD7Rw-zgSG{X7EUUI~VCdy$wLha*oIBW~M=W*0?hn9i#&URMuT^(DC=Ka>(9E{zFp3 zIAiUM#6}Jr@QXb?2~cS^<2ObHBeuHBCUsF^u=?^)OAB|%3uiwm!C3ubCY_nPL3>eg zt??XqFxx2h3gaW>GYREXoxKBy;zSDBj&XOj?{hs!F)GqH=^m=qAV2vSg5cisNE^*X zt*Exp`nyl77KRumOG!FX(@rZ_zzo>PopbzmcwC)9bOglnX}}Mi-1@+?NCpd~Ky1Tj z0tjk|7>{^vrkigj;g?3LQsWrl4`3D6f&X1`@LTAUmjm+YH83_5#GW46-u&4IpO?i@ zXjMR7cCt101?7Kv*fULs#o58Ub?2<m!1H3*w4^t&f~smCg*=i=Z!G6N_?;+8nac|> z9oYDmK5ii_MvrJ0v#UpGi!b&sMF5J_JTXAhTp1zwvIrPjTRup&rjKQS`KyC0WC10! z$WYVLzpoLAzb|D>PYE!w!}y8S1hds4MPDF!p2tewxzt3^M55Ak&x|3SkSk->h4HI* zin_vsVM^Rae>?z4P#>Gvb)D(pp}(1aC>t~24rN9!b>h}^Omdvu=)h<tFh5h+CCtN? z?KGw{usen2g!o>p@=7knV!QGo{~C?CSSmvUA%Z$Hs^a_~_Rj-TUP#iVe79WaZFSNt z+M4s*^SGUdi2bI2DYAO<lK6IWZ4~-C)?}2e1RY6_vo6uC4-%$iooS%0%o!81B?LE9 z9y9V=j8eQj2|DpK+Fuch0sXMRQ6_um1LzGx8#Ez{&$5DVrau(#KRJWcMQN-T7%g9* z&l9;0Ccr|Hw;oJ({^YeG!zr7`kRNl%h%y=c0>pUd01cOlUaO&zfXzA`@k6pXLNN7W ztQen<`*oSpP$TX%<sFXot<OTbl{OLKCB{Af_<uT?nYPOlmq(4+&n-{1kaggG2dTnX zf?nU$Uyu_cMCgmbwwTnNVge+wh6lgq*vcN&vH0Rw+CRc-M6^98eEe;1j}`m*Fx3VC zUdFahH}V^Qb;KPBK3dPb$8DmQE`^V!vjKXR+bWE8hlgK8fAbT7uk0NJ_aGy}_(h<1 z^6UbAVjw<83CX{gv@|exxtlc>PZaXg6>fJiX>-}u$7`U;iUj<aUb&fvXFgktF~UZN z=1YVYrk6gTVYVHWag}_GgmihpOXl=q9ELm#MpZjiUFP<we4TlirPH9=G~y;dAst<U zPdz-F#-m<}YdKH^CSw^<ouWQK&iEYOQ!sZ_hcLqx`;Zzl4t%>@ueSoxOSwyn+MpPF z!Kxt*%EPa1>-be<E>bV8Du3U2r2h_t>LktgHX4|}RtN2%M%f?~>IJo+K-L$?6u>xK zbEYGWVE@GO<{Qh!!*d|_I;3vWZLZ1QKGk&;Y%L-3vO5A7rZm6EjnEMD#Xj|K%Xb{w zBU^w}s(Hk3(#I+v*>>K05Bh8WeQvm}KF(S@dJW?zl90x&IK#}p-fS5U`c%@#MBhj* zd^;i8cf?TEw*3?vOmi1g<#;4Ti4CxW(7o)NPBV0y<Ui`LQ{g+X1u`OO-$(ZkAngjY z&)XR-@{}?+D(=Ri=25TrA2zU4gvv|l@n+WrMVO2wtki}Tmq-4ym|kEuEv8Fe_*s$K z7t9}Xb<vn!4Tn=_qXb>T((uE87^<(BTc?NR#zT0F4AfX5k9ajH&fOf;@<UVJ^czcG zSPgBO6R{U$+2~Idtui-Y#+mbue~YpH@1FRXK$Yl5FFSN~mCRx;1RC##k+Q9jfJp0X zayli5xO!d$Y%rFCTKl@0p52Z}mhVc){q01fvrRghs|#-@Vp26yo?WtEhZK=&+H#bs zd1fNZ^)G(QGDF8@ni@4fw{kt$#K3j6ZQI)fn|$5OnA`~E3=5C9;01i|(bEWyxlfg4 z1Z$+)nhwM(sQOi%(?#bKBm4^_g+t$n85^#?qk5*n<NfqE&oyvO`#D`v_h)+gSvcM) z@%mu2w^w)-OBuN2D}1NPKKu0P;z13AVq|yO8ozB~Q`Wzg+CtQC#(0YfrCn!{GCYzi zhdvWW)k~8vKhA}J!jIHeywMhCcBWZ0zKLHom3Xxx`l0Nz#Zjz^8ZX4QP~|gnavaJ5 zAFnLo=~S!o$u$wcb?cUID6Vn{AG2+;3DN&%FzS*_^w)LldMX}jFSCFcyCfu*AQq$y zsDSuj;e!Ui&XUW_%sZ`9t)!^48lzXsNi(P!T9mE!lbwmH1~)7$9+!>__7>VZtVdwJ z)aV*<$@$W64dTVeAn!il80|iQw0{v4epK-FD8>GOi&f5~<mwc%pj{lrbvzFmz0vAp zKV-lpO`nLkKmf3+MdDHGCjjx<vy5<1^Oj~a;YFUnhYKo340I)zNMD@kuO8(6RGfGR zL1K%?>3&xr^D=^<q{Ks@ae*i~Slbl1os~?BhCwzip}2`jB=In%!>zl6(3<6&1lLk> zI)dvAD0nT}&dM#BoO23Lmr$hTuedfM0!4~xvOC*$l&B6w^)^b=_59EgOqzE)@hm0p z=4-}1gR%E|1Y2+jp@b^lAFMz~3}l)qqpa3AxvgB{APpJ+r+?fNXICB~-o+PT7&8Kt z#u<$M%1p(1_K}Vi9+Mh#lE^M9&q<%0aj;i4wPHW2XvaigtX|;BE8;mx;fKJMu|O6B z@2Fs%1@s7<d>AmN@!9@2m@+eR?_EHj_j;!UI^j42Waw214Q=~8Ir&UDwxw}Hn#rk~ zbu-|__<F8K#ug@3v}W~HbG;)OHgsAq#@F6KJxwYx$Hj4Rbal(3j+twGTLc${n7k>* zc_n&SffGQ(k(YeQpUTq9I-fxU8+(~A<AjM&Kea6vBGIqG2Qr4#uve2rP(bKWP~O<# zbT&c2g4*P!S8f(5Pqfpg1uul^C=Rp2jA7l&UewGgn4ngfv<Do%=d8Frt~0dBhbx{* zG*3=cA4S~Px*%%g+9oPQAI*_=@+-#lXg~a<!QABUSDkU8@vMP1S1qg3b-a9N{eC6& z-BVfYH33hf-rRP`8RZOSEo^swoMZ!jUPOwp{H-ateV_2|MfC;hdI7(3P}0^FDvB^_ zH+q|!`VqX}2JFEZS#B(*5i&gEkr&~YlmGj(t7F1eQr=o2O#f=49~A<{g-agT7*!js zAqW{lRD_au`3%cz>_iqt@st@+i$6qzX;Yn_SUr^GJ@JZ&&w9Z8jD*w6B&L(%)SKbz zUpW|{V=452&nzQgVCwz~F}9THt=)XOIH)G%jF^R3Onq73mrb(3`hi;y8t(Y0V}%oF zlJPUe=NGBii&E3SN)d7&5cMwBy03lFBMm8LW3y<O#VWoF3c!MILq;VAbhQt+pvRT} zo1=K$hkssLtJb4~aec}OX0FCO(DDS=d&iYJ1{!M2RvcA>5UJGu@`ckoin>KK>*!F= z|D-|uNFePjl`D1*kW>3=$;E`p)yN;DjP3V?^aUV?7Oce}yy>ES)xIXZ!8hJ?yMt4J zWz_>mDmR~EVt4znUkXL3I6p5u^#sJf@LL2%?Aek*fmlCUCeB`AhkdZY!9uL~MV1U6 zPoc7cXpzUadF`!7K+u<Fr6M6_;}|!?;;DyYD=#{%fQ<rpRl`JZ+0`uwt<xKC{B_Yo z3fL0(fw&8!J#~t?;*k*q-P+DOxa~N_8Jn2hfD#=j5Tf&eBu5o(E_~RcfLcGscUAGU z4luYmVes3HxFmN2v_y=~IM>Cy6v2b3CR5|~hep*e9m^bfDFW8pKXB0FjP)VTUE?L! zh9dKIad$tp%i#cA78uP$4u0X;q1;D-D1~>AaEP(YD@E7Ln5(sSj-*cux*dDpmeC=d zBW;C`Y=q1{9RTN5h{5TLRa&7#<xXP4OJRbFR&LpfL9@$-5C+YlPE;jTYV2NKgUL}< z=l3?lKSKACV(kGor*$;_LWqRU!nmw}WYA1sL)YfskTuGAl&G|_0lG7dhb`qqg?S6s z9KGf00AN}yXhkRPD98K|rM=MjyjnUjT{v6&3yL!vl3_y3`4-)RG4l6}I8j2MD4ylH zBC0$L=xJ=kj(cr{pz8PciU$`&S=LlgcY|oU<$S;?L(o*j+oxZ5sZ@_FN~5KO%aE`( z73>?_6~CHag`cFBNAB}J&j&-KR5Jb<Gk%t?KsfCl*{q2nkD|Br7MHb7KuAnvRs}sL zW|p;2!S%Ae@1TqF;-Cp;QDKhT2qpnI6vE2mw5X#11<sq!a=@QAw>%>Y7<$tKWQ+j^ z-T9-bxYK2m&(>hG_4GaZ!HK^P+;8k$y8=%n63_cWKPh}k(==PY<c+p_@i1jegb9g{ z9$6CXKc_=LE}t5aSfEWx(W!D~D;y3s<qu!03+_XmyhC1cY@owP=1D;D;W}RbnM?8P z5?h?ktr4A^+0JLH8qPr9E25df_RUUr4W{2pKyH%V?O*@A$d`7PLvm;@+sT3p>+uD{ zs6rZcMs>&Y=r95`-LD&!+hrf(iXbZYoO<%RJBr=rT9!rl!NZ7bciwp(nZVpvdw!xM zq4&aiERv&?&}~!1(%I~Jtn#^m`H`|wOe8Q^z-O31aeceEwL#Z}C!Mlx^7wOJr5Y|a zmakg~X}E5<0*CFs-@B6JlR`)j5`6yxl>Ea@2uO!7ly*lk`VPAh+R|5&@6y!zlqe`i zf$jk`IvNg2PQyG5f})mP@I;m~R5%vHaFW%;J@uXzcy#|j#}&am1Y|Lhsdm`WVO)r0 za#fr<u|i<`*}!<)BLwbrxEW5iU|^KRo8yu7Zj7B*MFQuZl}I-yq>1X6@P3eFoujs2 zZ7`{mV+sRG>i|+D<f3W?hvu3TxWs&Hz>x4S$61Do#l9Or+gX7vLRf18&F!B6siz;p zjI&DQd8=vMofo&I#tHfn9M;{A^-Ck-ZT#u}1iuIFlkSSP6LJ1I!9<^XEf<=fw*}8A zR(}k7Dt~b@SFNO-$~i_9$*@{Q{(R{DNUIOO*#s1j?l<WSZ;?X*k4+?xEGd^_dq#!n z1q5oq>DASvhN}vHlZv{)XcDsdHVE1lfQ8gB5Loy~*cRvw)<X8}x&bb4OY*iCOk<?i z_Ge6dH~sbZ0BiRYQbr|-u@B-T9OUak-qROxpQE#krqSwvRt){87xWkV3%P~O5E}=6 zg7RDlRiDWQE%<4{87GrF^=xkDxt@#x{~17YWIpYAL^P?VbrOVh_a|DNz>mCRrv&cU z>y-Fw15W`$!wGMt=|m2xjksdnDNBzuSHxmT6W1T}l%S2KiwyH{BFT&`vc$Qa(gnE@ z*b$Ow;fCRchu2}Y1mYE$WP-H#M45nAc39;Pf{cJ6P~&Br)G`(=rE|NpCe3mBf?UT1 z)Gyk)nIL)M=9$dcPx9DD!X9IiH+=%6)Fe<oM_sT>cz&kXwb~)sxRQ_xxKjT&5~3$x z!P?Er9c~NkDBE!AOVQ^YxIH5P;N!(%5d`JuJ>ErlU$^=jh1NwiBY-)0+2*%6l{73Z z1Vj-+r9q(IUSY}O!tJ#b;MGp#dBSv2taHY0pj5NeZgNl@rN7DrS_8KlRv#Vn{3N|v zL5T-7nJoUDOMCsxxAQa|f;AX!q*`pY=qk_@<wqM-PFx-iCjX?t-VQUB{!avD-i9Yx zWMX$yhKJ~h*BB9D7Ip0l`S39o!Ba(d`@_Fhc`37z&_LPi6x@xzZ4Rp3t(IVq$bD!| zqEvq6ttwo)WL?-h&CZji?O|%PHeC_jq5uHCAC<qRlt?7%@J2|r>Yo}yQ$uUFI7%7h zEeD~pj+?e*lmtCXsqF;>Ju2%JwKv`4cZqw@M<7`sIYUZ38QG3UTuNTZ&&gr9{I#k% z&R`8>a4Rz2H0#HJc7ox8mhHY3Ktx3%&t@ydE^9GT|5xkhn<%m;gB<X1zlFOm4ro3) z5bYZQyC6W_mVG_n8Q8YNirejrUwZAz@zi>AoaxU~bQX^++&$#m@>@y(%M0zZfkYR* zd3&<Z)BCPUQ$k%&vY9)}q;WMbW3#2-KdcuFHX0{t(RSEvl4`!<b)GGs_nqu}V;y9b z2N}C2+fPM`7G1dAI{kI-+(A6oeWe9YgGZS1gd0?@ISlRKl3?>9$f`Eyqeg%yngRkh zZWhbj1wnTpD0Q*~u0RezP{0pW?^I7rqva^&kcbpIb>0$uM;C<Xt4~~3=z)GAh>7(4 zcWi;N)#WkYT0IKwd4W!S9=q;XA5U5D$hw_XDbq6q*J!CD(2RzDPF1IiG8=Zvg@DDp zUb};@5yDT<_s-m|PdQB~HT<Yjm4gfH*BvuAY8!u2UsxLDo_fj6q9#>2`7u9vSHR9! zkWqo>!I!y{FwK}Dko91<I1&EBY&4L(L=_b5DdAp~$Exq4r(S!v+H+xvETHqhP4Cpy zv+bOfB2Z>@_mXG~$yn$Cd|vNsHHy_y?qJ9Sqn4D>B8{+)b^9aNpE4~FlbDkJs61~2 zpq{-LKT03bj*B-%Yl^dbl`Ds3#ndA$Vzd&ki72ZZz{ITavQG0gfsR5jx%ry|8XIB# z_|>Krru&cNnQn^C;z=NTcmS7BjSv8byEL57_x7;wrmf7&zr(Gl{08s)o@LQtu(V0S za}?<o@n8_R&^0@dp;sXI2Iz6XXw}D)>8-=n>dqxG4B(F?{e(}}$-~8IcT4*S*DSvr zN|#m`y$iRl1(t)^P!0&Zl8h*uSD+~*?znDjludN#F=?)j%a$q*YXO<{nL#^}e7%3V zcTqRxKA)km6&GXE<_KISr<TMh<tq;rRxYt<Qu74T*o*g-$1`^fDyN8PsjBlLg0Bxz zG*8JNIm=edpr_as?X@>Oc_<Cs?RgEAW^H)L6foCf;_a0>6UU|HST>cH1A_guup*sV z#c{vI&fS&?i>*&?8#mahuJn!xh}=iI9DrnEE|WKFQNO-#<A(hx1jSN<GfebHEmw~9 z4aJ#li{;rMQ7+epMcNy*IdAp1i?~=A-3~;V)F+8p`D^ZG;yCE^9;h&4+?jC)ui#qK z?tf%Jnp2^HKyLmKgiTB9xWpLA+^ko)Gci7VP&{5(P3m!GnqO{Pj8fWJ-@hyS@O8#V zTMcZ!uc`1&;x?R$d!qt2NS&O9B%v_I(Q7{kcmc5zk%^4HJL+g{Mr=z#jL(Iql&*}! zqOId6xPrpZ4Ombmcw%75jPfuuZeFHb&sEg^kwA<V1dCpyT8*CmV6vp(UEJG(C^`^0 zO7OJ+svi;o?COiM(UN#TA&ZZXQhbw4)Cs24NNnY@hJEI@bY_u=9=}$Ujv(xH+4vB= z{P@DJsGL7e5FTe%RBdjAb8i`HS4049;%FU2kr*FQNDINUQ;A_>E+Nw0mN7rDQ}n^D z@G!Sz-9wNfpHPo>Dsu)yS_grMRC*$dbwDW!W4jIKoRlJ~bdVs0SQ=XUpZgBTqrNj} z;%5gLhi6b9IgDjB>ei#A+IB+eoCdj&Bk?LT=(#XzTE^~xa<OyN-J8cl)f?UqiNX@_ zDduoD)c~CnzmZA!!quV112}yKbeXyvWh|FSykp*z`Wl$z@U3>K9-ym&+@*S1OSFEb zn1UYZf5J+cimw{{wAbEATWg4qj=0q%s5T5*>CsE&QbP8*$~&Dp?T8;CtsJvCBhN_P z6lS3qDG(cLgDsB$5OZ-)DM!?|`5|-!;`;;JMLS|A>_k0RWw1}8uA$!EiEy_`1)26W za1Rji?Ti^*=jN9Yco=hXRhkoz_FRPOu9m8=u{ym$$`){ohAue$s>#fkZgqzOjJ{wL zPGT4S<A7*o6o7Rt*QJ5V|KzDhpyQO5-yq4%pgC0I{)kr{vgvUZLDWJiv#IHi>=?oS zEWVl4m6M`b-=~J!e5SkUJB~=_>?Sv?&n-k(rbe5J|9gf*i6&E-B<zskZA~1qcn#Ba zQ$TPSvES{FpC+|i{*Rje;E&7<;A=JN_H(2irappg%skWQ+kq|q8o)%b1qN<2-4E1{ zc>8V>onACPn7V%AAF3nFV;Zcf9sO0iq=|hq_!oYAjH-V`#Kk!<KuazgQh4k$<J-!N zvayN$2%+$m8qWRbSk!0{fYgSaMgrq0Ah-ZP{N}L2>IJX#Wwr-Q1AOGW;xWHiTQiDy z$2J8I?cifx^ox>P)l0Ft(i91yL{%PATT4X<qH1;tehszqf`Bj#!b>~IQ~c;$Rfn&l zgncCE8G;IInGrZxy8;hkOu?C37ycc`=Zx`lJMKE@A68!H(ZjWPqou}Q$5oH-RDRm> zD{8#~+grHg46T`EUO+32XZn(!PbhDGiv8hY#D1ta;ks`bHMxKf#uJ5co5#zR@myMt z=kwxfXXhT4&%Gv-v--LWOlnVQ_&}cLnk=7@0lZREg>lc#jhQLCCvH$i)cobSyPVHl zqBQc=`2BOu+r$eZf8wCA7!d>MN?HM=z0oGPlmDvca>;k76(%RxTR<<guqXlqW8R{d z2sNl`V1RNPy=d3Ov{Fh1!X{D*S?a4Yh#vN_J-;ys6PFO=G*}^C^u6>sDcIb1z>`C- zKc!{PP<)#xMYfqX8wX5X0ycbgF~Man8)-~3;^x23IooJ2LB5zL#+$1)B82f_u2J5T z?BEBlMw}&@7c0vcHhCdKJ#xM>m{|sWf^z(VYS<HxT(5h*0{8GD$q@cr_F=1JK|;V! zR0mc9NV}AZ3<%WK%^l&igW<7ey6CAX*GWb?yeD-}-HW!yN;IyeoD-Y%qw$)MwB#_# z*DKdD`dxJ|2xevKTvA1*ns!sFpE8V&PADhklZ#3L4_4Ccyy0|Ymy!6epNJ+Ve<Ozt zv#s{`VU#v7f6n6FYE;}0oGKvGLQk*6-_1%{EP(agN8baHi|E7fz5=&9HT5JOix=R9 za0V|SbA13HPN}jr*!(X?sUzx(ys~hLh{ORg^N6DISvlPozJapeE_GndH`9e|*speT zNyB@J;L+Fgs(%tCKOJDLGi7+i+R>U0t3V`;WgUQdCsC&~sS2E|Rd&;T0;?zS(ePM7 zo9fu~=I14d%f*X>?5G2M0gs3+J5Wv!g;shfZ;z&9FvA~?9)2S*&OHH%dKIq<D;66x z|BdUhRA*fxFYrg7>_{}JBNt!CZVOtq9u=R_W_i8vI0F$FZoUiDgG2D78;gR*axFRj zMWB^@rJ!Hztk}VgyxzvWCZa$tId$7hg{(@zPR^NbIB`#1r$FxNnbtj#kUTROfQ2Q( z<&5qqHM*X495nD-haR_i&Gdf!#kCngX2n<1)V=^l1Vy7NPjnr7jz!jUJ({%1CEzGf zm1d_Dt9F)vyg_y`93IVVsgC2)2yUF*MEmLBa?7cqYwVFCagBMcZS`A$7nR}r6rJM` zc@ySUJ`vJrmM!WY08X7t_gh)&Jm#VqfVs#VEF$@F6*MzoYKt~gYzX|_6=(PUxEI{o z!)}VT*&0nycY7d?B~4dh>OGbacD@17g;N>6q`LB?)m;Yz@LSb0uFg1z+ksr3EQu;R zln=HL^P}1&u2f3`l)h7p`9A9zcO)bqn}a?GS#52si>wtj0^e)Z=AhgY(-w4-F>T~A zD1pPFfM$p_lx2)%k@>1g@6?>S|IEM2r{{5fd_ad<_>ML4WN6>$0KgjcI=Np$MN@@f z@)?9@vFdC*Q8tCY(-frPR){x-rqu6E2zL*GWS+$@Q<3vQcGGrg=x%*(dfpYW5Yx(W z9uY<Q>p;cr!UDAo_bUd1nr0J`BSB8UUP>eAaJBdxez0bi0K25?H`QtSODJS{nA9U8 z=aKSpscyRT?`QxsVKFWpuoj^g^ZDb}7OI=o-s$CR7is{Q^3rb~e%IxlfSsSAqI!Q( z3ylFPSCtI)r?<29<#`Km)|_|Q*V1pd{}IkI(8c3dM5>JCL&9)n3p>&n@7ttJdGGQW zZBaRQ5k?`R|IUUjbFA7@`wo{reT7;gS~uFEuZ?YPy&p}wT=zn4@zDusqfBc>)_y2D zP$0SKAvn;?5e!lkbjj{AD9zltciJi|qEE(QfZ-FX;Su6sAfsK&lh$<Dr!JfUBY_>^ z5mYxmz0&kSC0E^_>_$18b67<X+DndT`M$hl79f_d!k+b4*Zq+Qo@$F>SxT3~-FkEp z|LbdiQ*(7N;MQac#&^j}yvS51K84pJVF6;WDLLizYwuQ5hXJ<}?Zvwahva|eIe48W zw=<<}0_h3jGQe@c3O!8XX#s7#Uf@5Hx)jU9^k<Mxau7{BfLQT_e^7+*_pb+m!_spc zWRq?a{Ip--q}G^nZj>Ws=Bn$TpTw80+@aS90~Le8!LtqaXzO^AT~HROpO|(&0ZXW> zI@GitIxys?>s?p8e~buNY3{mQuCQ{0u9Ni{c&R{{^g1GsctOy+4AJ-)5e-ZT9-aSV zT>()#Aa$&+%JZ=NUi>AK%^D5x93HKBX^|lqVp!TIk`iEI5Fqq7!V6yE$AZt@A5Hj1 zhWUb@ph)aDD+I6b#ee~B+H_;+X9&2wk8E2)alNxcDl(ei$<E6h9)C2m^~*<<f)4xp zx}gW{WPJ$aUT)XMF!Mj8pks3D+Ud<xr9aXgut@J%w{^YXtE={6J8G?h^7?^gU1nr? z(XU|_WO_B~f2vC}a{=uRu^>!kH$r6wNbH(6da0o7t`aM%Y4m4!wt5yM4}8+8Zde;E zwJva@M8Mk!25T4{i*Ewj^m&>JiJbKLxgKejud#Ulz2Z>cH8e@JUV%zjF(J!>YA*f3 z$U(ah`C9GdfC{E2d3)X=_M+vjP`<3iV=#vHgPnwxP+Icuu7r2Zv^DV2;GH9adh118 zIr#e%jVj?@N}JtP1%KJibPRO_T`HwYYcYgit?_{mPf=vWY{~_K+q$dk|N609go?_2 z3hDs&>~GC!(-3F>8XqPamh#PnxBgQbH=x&zoG<SZ-07(_n`b)>kYjm@6|ah;>qw>p z>s5dTDDJ<VlFE7fqm$p=*vpJru)&*h7HHHemX5a-7PDwL35!V`hW|s`AwF-S9wzgz znylkKbzV4W=MdrTz<?k)h9`77560Frtgl!uYwh4$9PXe=+EO7Sz82&?*Y*7!Q3D=U z!Y%AKuo!8B^{o#!Qj~jD^?Eh0PDsZhRgd!awh5Qt#E$Ty#BmP(h}ity-v#@|IrcYI z+-(Pl)y~H&xID)Cg;gWXd=~h7s4Mv^1hUNgxQR4u1GTmPO~;?0lMzibK%W$Vabvbk z)2pqcmh>i8F+CUsTijErEE=9+)3RGH1kzMA`4QdbP)vH3R>i!xwcPp?#@>h3Abg&_ zbHCiGRBo-9Kr!D!?6>6E2l_E~AX4bd-)%OxfIMz}Zkei9_76=!TDAYVgbM7uSp_E3 zCq{>FS?&athVS|u=R;@Q1EKPbrtaOmoKH$gj~pE<cvsUdkYWrONz|%QYFK9Y&A7I4 zGozikmSVq~)W#!`ZPr0>ZeX$VgEZf7XNl4>SbALuk4eeo0nFAHI*=V5HUP;AQiznm z7021c`{BUHBD9xzW*Xfnh+iTBKiA6eHn;TZF#;6;nQK96?3~E&VIBNNa^8@iMJJw- z`=OKo02Xyqz4el}ODm+?E@(2ih<dbum90zR49LoeD9Q+|`w(m=gqJ7xUV0At>|u1J zq747X?Czt?r)-edMs&a)9FC}YolFxy<swo2E=;&UyliBeu0D|BUSQZ>J#c&g;D+Vs zHk+^k3cce)k+|6{yXNV;sBuO$ZGfjJgH+$KC5e<}{^wB%?%5*ej`*kJp!@4g>B0T+ z9myx2U0O_62so^%&%2tjm1}VFK0`wQG$END6F4qWD3c-8ZW=N*)WPbS6qXao+`vIb z${nPg5aFhPP8cSXFp8)oUc^H7Xl}^}2ym4s>YDllKY|tka>zHw0HqgumrjZk+jVjT zwHCrDe@{UnWsKqT6;R2j4R=Ve@KcG$=P$_4Jrcn9sS{@#97HJjBhX6HBk{L0YL2#- zgQ6B}z7e+O<1RhuVQT$cW)7HCV?fO0(mY-ZdU-S8o}Kmarv0zw16z9<fDZQ+6q^Zn zP>gBsnZ`}8ZP3#V!gq}cEUE|8g#{5J2k_@HQB9s`OzNuOtP_>j*WVPDaXG~*sKDjW z-~;^h*=&{%2PO=((r!-=%u*NZUD$D*m=LHONDom*0Wl+C2&N$1FnXBJ6SqJ^RpmC6 zw_=xl$ql@G_$C47femRm*+-Q8Tpc0Ksv`&!gS9xLlsu1RK0_oG<_{wT&PsHAzN7t> z$!+c`eP4%WMZ-wbaTjSc(Rj1fgbqict@FdoBN+opYKk3laEmosQ#9mO67Au?=j>$| zFUUj}J^vPY?m63*;eK@ZL=GBR^e?u&z7xXULy<JLUYES+=o4J3JvEGPyuyGmduv?d zJVbSr3SvV2Nw!Drpt<q`3;73=IG>WM=a=xTlwt<qCS)tRgacS*?0y&3BK|0hu^Mo= z)nxM$?4t(fJ4;rYdhwJZ(s{HJdpPKyC5po#e_f;^t&~<oGQu18TRE-dl6Jl9dGOgO zx&p8wu`4(x^1UXw73H?#@0ZM&X~r)dn)~VDk0#~36K@YhFxE)&Xu^A(#tT%-VRK;L z@sxqt-NZtnY6QUHOPZ-^Yj0Z+uvl}#r4pU$e5X1P{>D&_8k~5)y=7558Mj=bS~t2; zd!19Xq}(I2&Buow?IyK{z>DJ<e{y}M*J9pMY_mBM$Jj!X&L|Dg4B&pSZ1=z6BrAm{ zNzALkid{b<fjfl;X44reXB#~p5jMvE$PiP_1@lnTe+9-<wtCV?r7#uSjak6V_SpM0 zuAGa*h(Eo~qS9gNAe3>POF|d{vk+%FQjG=WQ7z~q(ROXAW|xmahEhp{u8OC`Io>B5 z7Dy*oJIl}ph3-W7A^@Xkiv$lEqtn$R<rtd-*N~cKO!kSJ+N27Ep32JU;be4@ei@8y zXe&7vJr34IeA43A6oKfnL`9hJz3$oVO62J~xX})j@Z+V0%TaQn*|B9JOCBy1v@tm8 z#QJSM0MNBEUjfPM#j?yiU+R|jHItQLT23S)jL#kDqMtVcj0~;t#&X$!ezG!$P{6^a zn`mPM0XL<dR3L2RS1QORY01VJdeqTDe>E0U_|Qt9#P(gpfoRAIaL^U&K3B!0j6=di zi+)noAGj>)ZYbATjIqE&2(;sPRv~HT@di+{plfS2?WHMzU{m>}`LvykdIdqu2Qx}= zXYe(}Hq~nnh{fP0^07I9?VFBKO>9X8C#ey3)p_5W<BysU_h?!%?2o_WvgNc0KJUMz zO7-*YPhj&@%q8Rrg*n%u{5SN=sZA?1YtlwW2>E^W38qHiyc}X|zktw-Az3kmA?n*H z90~lvW5{LW<eo^F&dWM{f?XLo`i!H-ba^(PK-8PjNaYcK0QQCOtS6PF%XpVKT970n z5=e+%zyExjIgpE9^TiiUPu-G<h6WTB)TxkA5ixoZw5m%q7}-Wa|L;dBbIHU@a$$tc zgB5Zn=s$1p8W9@zfi=P$`g%?~+=_JLeHy(;A94u`nn!b(szWk+2X)I@@;Z48xgP2b z!++D&w`&?pE(u;i!)cNz&M35c`mYTOI224h)ePo4QV>5x>aNZOMT{=6%V0IzJiu*9 z$H;-8b=smdI&YhAJdY@Y@NKFp`i;=$+YcQ^$VNGa2&lQjdcY_am{`+GzFvMxJ-XC| zoKt-Owy|dLg9)nP^#$eR;QR9p=HNoivb~B4Dx#HX!|?OJK00d(I+;L=9*1hxXz=08 z9gN}0Kqaf?t%o<jbS!E8!lZ{sN_>d^?K+H<yt*h|HA5mMFlIm`k=Yj!vrSjSLYIpK z=9Gg}0=Y}7`@jV7pL~nQ%jQpy-R~|MJTAM?t3}i;_Aqp!b715Zcdt<!kouBawO>zH z@R-MP^yBP*Mol;okU1};flW_VPR|iLTB`ecx>C7(h&Luq-t&6457_9Cd=Sf`9!wpq zT`-C(SeHtK3o`4C9U8&~vsJw~F0izRF42p*Hn--oGtWjR9MG!hV<=xPcKf0M>bAfr zgiF?XJ+$t;BFs!%69bj-O8Y!|p}SZB!ZWx{N4sx%xCSH;X==JkARe3S-OhW|Gry)r z48w-d<8*r}>mBJ#3gV|+w$YiL?0V|C6RXO_4gxRxBK4)Raq&I$jUEpZ=yURw4r(hX zG)r>c;_eYp0fE&0<;xF9MZI@G28zfJ+X*0|7Mt2CLgtKy6N9ye0#}Ezc`;fD=Mi-s zByJ{-AhQ_rD!$S#J)#&~%fUnvlu}=!5Iy)Q$iDV^0fwaYfxUb0&r%iH8N^w-o=dXi z1&ES>vkg)JHnNTxhp^e-tsco5n`+D9_)17ZbD9TCpyL3*U`j9NYsnt2{Q^M+!cgC@ zQ8k3Z_xVA4HfDe5^)Rb1!#lDR2U0hN^;*uhTBEd&aR0vVbMF-OU49nrk$zll#Zy_m z?RJ=Z%3{}g&qYjmsjht$ofA`~8)u-t#(X`_zLfkX%l4I!(K7caod#jy%eVs+JAd(~ zhQ>;V)h(CPE`D{0Cu<pagazw@U<N_Nmcu?AR=TkjHl1bNP$pjfx=4NTQhm639|RU3 zdOS|_Nu=>r^<U{t9YC}pE4T7&R$+2A#?Ezl%gs&ZtT-)p7qzL>bHBqncg%9Q&%wom zR~UMtEA(SI<8R9g3e_vPb&lA-HLsz@mUK4U`uBJVEDhHKdR1c6!Bf=W6w(W52NB_} zHmO2ZOr?3-@*iR9*?yw_MZp3Fu)eEo=ykx;)3cLp5;Z@9h4wQ-A=}21g@)0EvF>q! zn!Cc1wFfWJs&ECrh@o>eFwoAlR>N;Ct~9(4n>T6^gs4zal<kUF9KQtM3bF29-)Ft( z@fJ7hwh4Xjo*y(2Sn?I9K`MVQXKobZU9_djpj1#>^3@w7<6vAOg`?e+9>z+y4Mxp5 zaOGqGep(XriX$iB!>$X`_5I<4d4C2rgxtaU>aE6IdeC>4#j2@Vf~ye*iFxyqqXt23 zeEH5glw80WI*r+hB@Da8Ygi+*dLZKtG`v;_to+S8igscq-rIa)EgN`6GZ8@TXO7OI zg2-YzdT?hN4c0lGJv+Twze<AP2xBKx3z&1NBlyWBZ{B{0v<ralDvnEkceNy3pm+;7 zajwa_c;!b2aQ<d!g<LH$w@u?L-mv!H+pHM;Gco)poeBMR1x4W$2a62Mjt4>c(N0vP zY$iKL^1*Dt$RAg%&P5VTZEu|P;-wz<@~>WAB$18{?stj^=;z!YA55K%bxa7*&|o?e zm~LRPFdZQ}FmaOzmv!x$W%b1_>K^)$_AaK&2s1AgQ-w#)k4ZNSnccZ5$)u=PM$QiX ztV&-F<o85-*+VWZ$dQE$B7|x2augSmj8>T|j!JSWiMX^j9P)ZxpYk#E?Yqe<<^>D~ zDT%NJ%h}^ad>8k__4-G=w7aeDWTHA=`K{cy<!<|ea(esDNP*$WmP3YlIc)%Um~#2z zEikz0V0moNG{o0)U2rMGy^_j8%L2@7UA+3E*ZY<VEwY_p`p50-{hhCY0Tkx0DO=1c zxa7DyR^G706o736m8@{^IvJZ;op76EHAo05S6&lT&#UvU@Rv(t1Fsx<x7*;7CVW=I z>;X?UX7@;pQTEV9w?}g-322ZRgxaF&xnXTz_Xwggwkj0}Oj*L2NrkElH*450)Op@| z+i<QQovS=0EfFD+k^;h9)f7?wEATdrL@XdVBbfjoQAAGE9~PnB_JRVRuR-g=F{q(* zizMd21*HLs{OqoM;41v`uGSHJk68B(_qKccNBa>%APnhj8u4F=R$;}P0UdVRE%YkB zHkSYETtrO#;U=(UR*rB~16tKUph{z*L_x;d{bE#GNDr0SKB>V8BfQM?*7K@BCAP_z z&cCRa9lcYW14%9r7M>nYBlhG%CYp|NYHu1D)5l#k<=HxLJ>W;&Vxv5+{#uEr{#o4n ztLVRZ6XxP>ZXy3h5dATm3y0J3vpsLx@#xb!t>E6SGxcIh-yEc58OtD2KAs%mZ`CoZ zOg9gFUY?@wue0-kUY~6UNx|(`xGDoOaV@I8nCR$eH6b2I@09ZbgRB8=Ak3N$;h#a% zL|ViaTXPivVy{R6weIGg*EI?3sZz&lqzHxCQwyE|B~I3zIwY*29d)UpA@I0{Qm`vU z#~0P_7Z7sM;XYX_B9tt_xKuqC;3Eg+jG8QHv+Jtp5#pd+5^~mE5|RswJ8;VO7J6}d zJZ%4Bl1}<3m1;V)qD0_HzsZub)84aF1s;5OJJGQVs?sk}PbBWI2xs#GzN_5?0S=n& z?<0v)d17=3<dm171xk^)FX3Gz05aTnKl#Ci;&i9Fn@aM!H*E|AmU&48x&Gm;(SV@4 za8+KCI~Unt^vU0F3z`E9j-IwmQZS6X1HMUK%Iz~t3Cg6VP<tH6u%1&L|Cuo19bg`x zyI~(9f|Pzi=4=K&FHR$WQWd0R;}pQ?tbERo(5tNztUNJ<MEIAQ{<1{x0{5Be8?Kxt zEzJr(I?7|<*x$68gk5Ij1Ov7x&8)^R+AQBp2xsVudA3%RlZVcxQPk-}50*oAKbljt z0@kY~*$|t6csr)tGr~^QL0<SzDhHYJDj&y!L!<6!sXkl^6E_?Zj|C#>bLINeo`onE zR_|>)hcWZhAO5ApEnfn$!7DG1Qd8-LN*@PH_lN!KAjAU=NJ2RUIp)U-M3E;i1A{Or zmm<f%)X!GsM4^p4K}6ytplt2%YKhw)Pp@+c(Nmp-SB%esD=OqeZnOJP<e(I?jI2%9 zcy^dn)_R?Sqq4#qm+inD1aP>?LMLSxm&bo8#=Njlk%vw@K3;J)h({+|@fNM)*;2Tp z2b$`h|4l5ybwMn~D(?at!gVAnbX7n6H{?2nS02?4Q~ksq(ZI}qwTyL^7x)7pppevE zg4O@O09Yrd*r$nT=@AU6Ga;lr7;_-nCMb6yCvhm96joDe6>XTk_r<=hIuc5BGX0Sk zKNjT=-o6_cY|~2GHnoe-S3pjQS$&_SC|;rfqdDNf35>76K*ju>09RJ@!|-Q013h$9 z=(5XH_-AmrKg^#o?^WxGKu)Z={`{oHVc%{U>%oQmow$-?{!F^Dv3O(SM%%p9IVHG- zD`cRvP?&W2br;ivdO-So5`yP_Un+l%w<iMEIhE;EwDksl`ih8?*(=z16(HKlI^2zJ z0z&2*G-Z%-H&cPY1X-;S;k9;TbUEAcz{ffP+=dUkS@Jt{)&Ws5<}6l#^^ljp=)Av( zs*fUfouRq@Iu!@PNU;lC{(x;`&07*n2p5<C_5!k9oXJ6we@G_ab=L>C(45qG5AwQ` zFmDn@5Ag0&p8Jb)pj+okrO#~}yL+p9Y7Nse9{R1gTTiHj4wR6G=)PpJ2((-{jGsfh zrJNvDlo(0s1)F8s#?P%W3EBem8ZJ1z!zdrQNg&}XO0t}FCq_esYY^qu=z$8KG-2!1 z>uN0^q9MNH{3zJo9fPABme9uj9S94YGAVhTF<VgUaw1H?<Oj!de`jg7x<LlN{tSvz zV$snlxGaE=9g$itnT5|e=v=qo@P?9Hh`=AwDk8GeEv*%KjV>g!aXK%6#u*~c{Ts24 zM2Vo(0Zdr^lQl4MB6D-|rZbuN=&3LfUFNu@jt289>K3nH7mwjP2c>rxDLewJuRd%k zEoL{d{SQM{25bo_=m|cZz~Bn4Ep7NaRwQ5I@FC5@F}&^kOQvC6HPsS-84<FvBygHF z#I>fw;PQYTm?DnoO1+K9Q%mte3IRfqZqWbgbL#oGnJ3zb@p>!~k+_~89|PQC>^eph z;~IzX@AEq<zTq>{T~Xo)#mRHOCjat}kI~`GbJe$kZ!x;y;9-wXOorVAm+@3U&?`gK z855C@N$}Dv@Tu{LK16yCtpa}EP~WZMUQ$LHC%C$F+cbaLCtlK}4dx{+Jy9RSQW0Zv z7lv-)q;fMtEN!wxVC-{Hdl4pZe3k;>Aqmtbv>nQYLckEQQ7}H01zMp0)8b$0W+XzK zje@=;ks244%YV0jFDgK$IMV`oU$S9{Jx86|6L#z=#wf3z@s_1vv)%`i%B&kB^TzpN zzdO5dI+Q=O;$xI@tN<V3FzJ0MzQtG#(*$>Cdj6g)szI}Sk|55b1<ZBKf+(gVR(~%G z2T9tmAyb^<>d|CLwfSpQwe4gYo;7=+zOIUPLEIuOxc8e$s<t##`H~3U1ah!sUWoVJ z$^`s6v0LRe)#mJK`aWx+A?yDuqBq&^jg_QVIL6>Z9jk4!P1MZ?_^n9hK*9l}2>q0U zcJ>YkY{xn7F#Ju)tf=-#X;7d`u!K?^;nZjVs<cuy%KmG4;>dw=;Yc0Y1?d}J=v2Y+ zFKiNq;(Cy)KP2J$lIw03(hLsCUpAfUggF1JEc?@6;Rw)L4-yG=l!Q<dUqk!CDA&PD zlBlTJ;|bgOYE>@bwoA<v4ZBNe15_^b_cEahrqX^5>~UL{2%X{oX)4yHPIdIqq+h~t z4+1-cNkY=xXbigXp#kNQs>x>Te6upAW^59E10X|>f|G=P^=3&+B-NukVV)Z*vpM<U z@*m?^gNwN`ASA*_5rLutv@hb%idxP{%tdBAX-44ke8Ed(3{NQm-dqPsK;!6IYTtFT zdFDVc{7%)8<y-P_os-RVir@=BXt&|rQ0<a~3tP~bfB|X43uf08WP`z6DKOP}N>qeK z`e{4&yO@rfspt%qhDDevLZKwOzLCU>T=5&q`|>6PP$K&~HC_&k1b;;bDxAc|?Xpei z@C$vYUY1-`B*60x&6uw|mULE<c$PkG1rqO|=2V2*-R_(va2R4hj3h*kElH9g0W73W ziDvre-Q8a{4^$!EjyAC$j@On#vaa4sar%UxpRMsR`~H=~V$>2g{92X6LG38r@13*$ z$Hq6z^G7o6rBW^g@7g7?ZOUYp;2-bNe6i&G6oZV_vt~0vwU+Pe2ezqqphOY2dS(FM z322NfLrH}^fhZO83Szw5Cwh+Kh(-rPv|MCv{i#KeaU1fQ*F^c>fn*$%5}&W<FA!WH zyZ-1`(Mh)bXq{&Q?oOVQM<)Y|ZArP0Zb5@AUv=Oz`TjuT!xuC?Th;-Zk@Ds66?poD zuljPDFU;rvsM%O*qjpb)BKJjZ9#Xe=gCs@LFYE6*MPmPYe)7@ea8^Z+U=hB6DZu<0 z6iy2IBum-;8PH>XBE`s-JuiP&3ATi0ZZjR~FR+RQsXYjTaH1y9IZXBw_B0e>Qajkf z9A|J8>o=<-c<q<*Tpo`L7vf%g3sz`{?20m?CF-N|Lh#a!Snf4`=WJ8|hN%$%zFn61 zD}DDGcO;ikRjbG6?jpC~JpidSC8W4$UuJ890X7}#6rf|rnU1A{K>hj+D3K+E;G$6^ z=5fD-gTTs9g<SD3Ga)RDczZjD3;gQLI0g{^o5+}HNJV&qz|Zf7jbisD=+leSOIk0I z_V9Wy>vW|QO3}z36*L>`UwW-Q0B}C+E@-+DL+YuC=jzp`hmk)r&yp2@U}7K$*PPb7 zl1c^xUsDjibDk#Pw59xh7tM5rBsb%{(4oc2_V@~oK10|zWfj3rGX~g>`xEDTrd0AU z(AB-(_wkoG#nwwqjIjI!#2>@&S8*?e@xmOo^q8B_RPz<+#8<%7f_roM$on*nhncU) zVX-GPXFt3*Eo|;_L!qtxZ&Rksv|RhghO@ye7mI`H?@)u~ZNw6`ixKoe!27{CmY|&o z!3SE5xBJS3Qk_IMjStUx51*ARP$0R|zFNdA>7P6=n{B(t+JytNg-Z7>2d1rWfOHgR zV`GT>j+s`rs8}~A7%YGY{~2*?EiGOb%VBgKHeCD{e=jF{T{2<}3>YzGh;FNb=t;4C z<iF904Ql@EuQRG`=I{!_@m1FjmpvptUqS80W)}N9G0y03o`ztA$b9C4*Oa_h$081C zLthr(Y7ViP5t3>f@Z`qnJ)ifkEuo2v<atAbe667HYk)eSbQqf7ti#Tq!!Z17wu)4r zd(2>>WSo5(<!=jSOLUNPqvAcpm9$%Y_JS&4h#<?~^k~%L39G5;$w;KT;>L$vIS*l) zT=Y~7#wKhAdC-R1Dz2W5Pn#D_iz-03<j}om2ZN_W_;#qE86pI~>p~2(i<LN-zdVJ% zfhbHZ*R;!4G)OX}lZj-3zr!jH2zq@9#h&yrV71<|-kUwyL7arl<ekb*vVHtpGo255 zHC-%3*EY~%zNS#)(KkN`1lM<tO+V`6wDns~UFS138rs9(Xp!`T5QlU*aM2&ML9u}l z*bdW>tcJuLV^<!vAI^2%C{beFDW1iJgbVJRv<lp^P~9I@@;3g$S0eNVOoR7IuNF=; zLyNZqehOR;vs0Z^y3{{4ZbKvbnz?Eo(YP;nueF~#0`Q}7jhOq(<#_<#8F4*{aou|_ z^d$UzJqm6rp3%rjFrv8#@DuceFw=dA51-Ha!H>slxLufr^a{Q;R5qmz7Tg%SGwQO; z_{^Djl!81A!w0}>+e}w45Q#yZ`p=~OCBDEW%F{@eFY){!@wuhDBpwb`kp>GrD;bk& zj|PIv3}v+W)fmP*1ISXj3(vIBVJWfv;M{-w!Oj@hgIDZ`NxUL<K!Hz0=;f?{SQ*G0 zd$}T^r3=B1gIm=3J2LP(TWKZZM@_AiBF=x9^oeb$tnjjUHeMx7?zX&5>B#!Wrzyk7 z;kK}+@DQd`tmtocUZQjA%dE0bO75%oxME(GoSSFt00I1Vj=E*BNp>+yr-5;4d>wo` zeb?^ZQpdrkgqJ>^{q6XH5ZRDQ!zB)8z@493hiTYnRSnQiA6hG<It~AYRuz}JEw7GL zq|(#{CU<xSsg@?b#wwz)kRB7%v|^(?7kIWR{JmOYZ_|4^;jqPymTJdqgit(Y|FAo$ zcTqbW-j6Qet&D`_&lvfNG!oA&^kxsD32N|TIG%wF)KUAtxDUBvve-!XB)1p)cZW<p zw;%_#nPfB5kF|_z4SdVX<Wg0QYr&GsDI;ZwGI^g8s6VTtxp<E%79?IHnKDrMYMR$| zo~OrF`9W4RK)8Gco$!W1(V~km#-X4fj+-@mE^p@2dd4A8cbMva9hzMIZ&LpuIlG!D z9^bSdIuQ*^)Bc7CCU<2<ySQf89tob$JH~#>m!Ez%Q+L9qwW1j3QI&M6vDd);<HGc< zXvn5IG)>~DyW=yyP)|XhGtPOP2`A};|BlHAAAJT6U=5dM<NO`=WB7l?SM+Ft^Y!FU zwgCP;H~hvGz8QZXS(b3_5lVZM4c`ZL;18QXTGk+RFJydD5>-nag+2&mb2XvYUgNU3 z*KGg(9tLCUr1w(RKi@WeV7z42M;Goh?=||D9Z8Jc{(i82S802trga@9!%Mja5I~u? z_B88<qDb7~Y}jI?fgwk1Nl~BPa#l+T(zz^|KX-xU5i!<kcP&<EO;F_~g^7}~Ck?~= z(>N{$YKqTd{Fje4{99~W*fHO?FBgPpSxXlJVoo^%&|4Vm`bi+hB}7yGB^$nb2m>?O z#~e$W_|Hi%X2_9&QE0gBd?&C@ngWSQ8M0~T{OAJeqJBQD9+c+|%8X3yWcd>DtTu(A z54)me?plgGgk;r^w}vJ@X!qlrrwMGU0f;{tr+7VHhoYxGA*&k=!nzI@9&i<0y%uhf zKA`eIbnMc!=h-4LTlKdKi7^uIS<Guy>TFxSRmer)6Ys4Ep~|26<x0j3SVm3aQM}TY zcI1wvqr#E{7DcmMJP!3Gqu9Zt%6d0>sv_y+9w&f7xS*c9q6_#`&-b0u5TEhmL#}{# z2*S}WML8<6!pGvv#`+G3#V5P=5+Ica3D2L@%M_KY=*OsZW_Rf-hlqejSPt*am$5N4 zs#8c&B2DMRDJrz+(lBxfWosLNkK-Oq?TDVDMGqY$p6GTC)Eh6APIGOP{WEStGbg!@ zcrZ~OM=S8%Qjn^_gTm(1qAVrLT1Y!6BF$*3ul8PagCc>E*pUp~TUFzf1ibx9;89b$ z)}5I-9F@u-cpQp949DJ510jLxP432<*>@~u^Vf^uh4e`#(EY8V{kRhnuvk$fDpIAt zDJ%TQ8*!BjVL%5h!O6!!3Q<s#_~#MU{G@6Zw1y5|%xK&n#)k6oS4AUpzCU(oDq6{g zp@9Kh<A7!dgQRaB>7pxMv@?>eY!!olV5ZKqg*gy<`|=}tl{KM9ixB@tS=@%|t=o~D z1%p%^EO9!?eo)M?m>vKLrH<M1YQ^YbGEcf&hNyfq6A0;;l+e32@ax!F8~<B>u3Ij| z<-rjyYxv(qh?F`3;G8-5w;1s_Qw)<yU{61@E|%HzC02056~vHy#ER{pEan35D30Eo z=-2qqsvW0qvk8%>bwWoUmyRvF@lyxh_|Dy`Ty(8MjWY6Eyo2$}dMK@{zSG}c8w}}= z8}RwNRlr9u8g2e>r%guW8ea|SQF_3)@BN{iO;3+g2(SeRpMJ_k>d}J@QSb=ezGchU zw|W5aK6)Hu&2~3MT5ypRC`+2*80+tAXQc7>2g^7^<oaCQdMX4$$M<c-IAM>r8o)44 z8tp%65gVc|G0DQ1BC_$S6~>(9y1e~h&QV6;WE+3OTqq{$-4ZgB#TFH0I@qqHwW<CS zXI<3DnGDV`30W<Doq@Pq-j<bncUZ|N<Oi)#Ix>{#9T8{@XWKpveo7b{-3tIS`A56J zkySeB`=eBl{Y5Rk5Chmv<qt)-9UGplo=X<WX!czD6~uqJ5dN(NG<cn~^2hz!<?xre zK_U4Tk9s)pRy^>IH+Osf)b(Bq>)Mf_*2=rNIUIs$MTT-(E=Ii^8|Qh>^Ck-$dH`Mh zWE7E^*IC8gM4KP-;XoJK`eGne;&L3a!NekA8QSXDm`r13EmwVz1Ls60h>C)4)5+Wv za{#Aet044R{twnY2&1b4xQh=Y`rZ>|stJr(YpSas9_c-QS2X=OtNyNGDSBxifQ7a! z$M1TjGlgxNWS;-IhjQ#UR$4{i5Oh{#7K&~?psab>s%1@<R9+VSd&F^1Dhun^X}UXG z%Z55R-PoCIVZ1bkWT<noU_fTSiK$1s%=wCr0_y|Ku0646gO@!RXUqn-%-<Bw6HXwZ zSfz;{PbifcY+Vbzl&w0ZVIAyD4+_*q{1?KPqbvZ%P`31&<l@D+F7$bWd!R{Uhd}Il zRuhBe{V1aJhPH`;{dasE*(gGOV)99auv1iiy9t4RmYFVj00vxEt7XjfY@+G1OG_5` z^;od`=*OyTq(w9wj_kJ+6oF5`0Ppy*35Lgiv#%LKJV{82TjH1M2|{ACTj5tUh<Oh; z*#%!jV!-R_Xn{_S?j@vF@jEb)7j8l}`3#u0W3qE1hCd%U3c*Wwh|v^E&89Y9u?2c^ z)hUF1gi~2K%MhFI4LYSFn1hfL+=dl)HXlC?srwSH{FyVjHR|g*K@o=lsYuP?tWzXL zwydP@^KQ0yC`^qL5y|NHHUejX?(UQ!)|5C?imjm{WGe@Cp=z6b{R2C_wFRs4e%*Au zh=RycnLC6|LPb}V$A9(}^jM_p&d>Rsi0(P&d`IeTzt-^*JV!ukO}_}wxLu=hCBY%Z zKFO&eRjb;sRSLl9@^}uJ%N75*kcrd`8m-M0u??pz7g`A4Z_d}G0}P1kBw6)73COVw z_FS2H_gp9jrrf-edlqJLA6IseNG|pBwLQ1WprW-i@++;$jMt3X*W-Om|K77kc;hOk z$DZ~a-H&@VKG$74OC6<Y#rIlx5e@fd>Rn7xvG?gpDoEk`(f85902G}zJ@iY9kUn^c z?HY$zeVE6prX2mFAOv6ftLR4LiNIO41gJOhwG&0<Lu9wl&7r}HA=E1kr&lw?AE>9x z3#0eQ;iHVge7&Md@q*q^h|gijX5Ly*2Ic7s7wl^#K@bT;n;aT*$FVM_P7wqqIwSZR zI6yNJ!wiQI!y%m?DN6HH_PAsFSHU48-Ui<mk!o;fY@T7^63Ht30w*JRNG!|OQL5RU z*J9}i{~W%{KLlhz0f4FH+SF4RGp{KAOE50{GC@S7)NDUs(VZ!AU}ay_Aj6K^kMy(z z?|PWoj%mC6nzt2HFT9Tp%GNC`NY+fREUt3dOHxLMlYQSo2G3fYm~4WeDZN3rX=FCi zhj;r9MAPpP#6pz>Or-9~?5s(U(zYc&yL)cVm+pw2J?$cS$Nw&L-&BzLg2+PDqYrFM ztDM2~@~-q!xJ?+7Sb4Jo?i-3|$vCChZy}$_;~q9w&e^=?P0Pdd(QyLDR3%pd(4h^; zV&P<CKhk=gfVOITz-*4xhcCL0*dq>SCGV->JxWap;&||Zk9lRkR2sX5k^^6P1pH<= z50e^nYT&LeX>nbz9*AiyNdOKR@SdU2R0Ds3T~R`#mr^(!W6kAUyevP+%utbeyUCj4 zPJMga$*nS&?mbtv62U(Zwo&Kt@~=HCZ!a#DhMMT=Mq|Kv`GO06Uk2?`pyc~)F4C}7 z3&zC@fLI~)($5lYtx+|NbgKD5xPpG%Gwko{q!uvWbv1ON^{xbNhUVeMV#-&Pp#awS zK3{*6B;pu%&dXW<<2ESKlN(l-3#CPIrqZ2dT|%t&wD^+dI2f{V?5oJ^E3+n7f>**y zu?B|zGYOw<qU1|DOQGK?WalSU!s}_~abB9t1G#!aeDQcUSo63hZw>;fwcG;McQ?~7 zW*NgcK@EB}kxuLc)B~EJ`nqWU*3EO)Ur;Pc+Np0kYKIrJrJg6u3I=o5IOke5kDo>6 zv@?Q<N`=TTi~^Ue@mJ4<M#!P!hq@q!oT_%yCJjK=eBf?|YVZctSkrS5LzeGEd)=hw z6<TO5ju%a+8Ba2>Vqx{pv8Wfb-B~)am~f=m-m;F;A)uA9Usf)9^3!G{;_5ntE6uzG ze=rBIzHTpO_te49!dNQ6gz#~E{S7*e+cxwDKqs;iYUMa}90IO_fg}M_I~GY+%HGIn zt+3T%=|e4Z<2Wp>rFsIV)KOuZZKjEh!-WCRGx@xa8h&T@V@?!yRg@h7TmEzQweULw z@(&1x+&$+{3%m-@T`^*9jwSjt=;xv)G(NVSxvi&t#-s*tGp~AHowB9NmM{J@W|~?{ zI2AJKNC;-$$pi)7hO`O}QBl2|McJ|;6-0MF=;|>5xp8{B7zjI2O36XBfb=*G$#<86 z(Sak7HPHm_XM?MxfJl(GLc*N=)+?z17-m+ZTSTx7gGF^g(JeWp_Ir&I1!V7DudjUJ z`^0Bh>VR<o4I{!6dVH`04?>B}f==|Y=*B3Sp#=dCM+T-MYhfmp5Z6@$fG+H9VLS|C zbbbo+b*IXvxH9WaAy*%oV&~vez`g;V0ijr^0iUfE7612$9Q2+W#+)blL>$Ywn*j!Q zCC`_Y<;&&m4P=l-lpxKu5;fP!4@-gM4@Ml9*BzKNAbzBcMyBj<@95-l$jcDKSvigC zm%cBaE56p{fTcv*_}<fwoK(nP0#-1uS_`xj{p&K9X9g;-V{))vQWK<()>0ic=pK#e zZv!G0AIbQ;i#$&A-5^sseya0ia8>=2r4@O@+D7JOZ_%}8RU~wl<G9~)*RC(Pj6)-^ z&cAg}U;f_a1Tzy^t$nRX*g?DVb@!IgAhAg-cVSyM52!)YJc;@29jU-j0~z?kjy$^r z#;zYr0}&5x@kprmwBV1?)oOI74H#5L#*$(g#U0+T&~JcMno(N&N``s?Pijj;7Gh5$ zEz3|VSP$~AS!PtED|H}#!8oI`zV!xD+?5u9JhR7x;)rJco77#Du6`mFG#6MXn+@>c zr3WJ7$FboXMymbyip8dCUve*#YefOmFxK5R#R{PPS29~gV)XVHRPIASB$$kWUR^tc zKbFeOcrG~)`m^>5vfA3^;1mM*R`-N#BmBIeNvm!c7To~y_jReJKB7l3aV|5V)xZK^ zA)f>0Cv(%n2ZYS#5;--G*H37xWnW@X-AGo#w~s?zRK0?xY#HmE71^MALfkjrtTO!m zw#wj5@>r^&xRM)774XRg@}Pz><R<;^8J+8qUMfep>*t&yY++JqW0O>n90N!X5`B>H z{Z6^_G7Gv;RM#IU7*)i^T;hVQ*<-9ujv!&sOiND;P+3f3w~T2`Ux;yaVfq3(l~vpH z2%;iS$*87qDvk^#F~VkoLAjY^bl^{+&Un>(q7{o|h6nC^0-|M{=}s7*a*?4t=7Fm> zbI;;{yi4s`g_1rqC|^Hx%|a5BFhooC`6rdAdTt%=m*Tz~3^8r8S8Wy_IIm!-K3hOm zhAC~mCUW0`aL?IE%B-KGaf#p)GFZia!!kptYGPEk4pyFQQ$n0`r8ODz>UJP#h^OE< z2WU`UK4SFKkva-Ub}ubVY*VLh0ExiEy|w3>6}cfuO%=r^XE8xlbIlQYA>5;Y6fLVb z@JBU*0R3xGgrP<nl9AuW7k|L-1m!*eU>yRuU~sUYQDU$5sxWXtyznDeJQH1ro_dA5 zEnvZ*h1uSO+8f?P1W8jrD((OFE+K)vl1vq5M^?tHEQ}B!B&x0&*L+Y_`|#wm>G;() z@hg-JtDKa@y7LxzadV(`+=XV9TtMH{cx;(!{gTJPfC~17{Ex^DN#s4?Y*`)L@Fxu2 z%CHFrcRuibS2tlzA4&*$`O=(-&`zK+hqlcxrVez%QzBcBQfBE}eKCR7X#B`3W`4GS zJ}>KrFX0>C<kofU7S&|g+(9DxbA%V>M8@Lf+%OJSM#KoQ3~|Jtki^qw`2g{NWJZ4A zSDkC_ma&JE&Uiud=4-;b4w+%#-X<AN^*n3+W_z0o*nA~z>TLLZmX$T38-G~6xw$@= zz$VJH_lM()QA4ktIRe))T_yAPMmn8jty|fbgusmOkr;3CY0tps`W6{;Y(@~UQLi3` z<sdbrA>EkTZ?v<$wr|^nJ}D1{>NOlR1CaGm&#>|tubD5nQ4vLvzlokrb6;S#K)KC` z&Q>x*>zz<6%f<^SwZ=!>3XJ#F@+hgDU%I@O`cuhNygcQ8o@P~{u5Z-jj9_t1orw4h z&iyQ2IWEs1HEvCEAsB@|?k~e8Mk`r|4=3I$3}M_I;u7?W6{v*B4Cn{d8vDf=oV9~r zWx#)73U`Tn`nFHzak8^=sk1j7j!-PXZ;_QlUmdZ18Ka3UM(W<OkB4((x0)%wl4pZa z&CgXtW_R%lRj~tE?-kKznWEQgT^{v#!n?TM+`H9aYiTz5z7jG1Df|UJ1pM@WctfVx z6Dp2|=>$94bBf~?{@Vg`D+OG07e?<!IB1$g;05A<NDv{Q5mx^-;0_qbTOhJ$AX6l$ z!3#F7N0)&M29Zz!kVxGJ{J_UIq`=9{DtYHbSi1b4b9PM7%=^vC>x*3R&X&K1^Q4(6 z#yrY@z$VFGi<sRftM1uVloM}UUc3IcH~~t#-C~1$F0KUxWsBHKjNjUG>1895dNC@d zXP$I;3DXBW!I%=HGg_tssjd(9K7-BG8?^a3BRO{p9d*x3zQRV~6U>_@rbxEN-8449 zU*k;X><VB=8qMGWymC4lkVAkFJA$Mszf_&?=KacO4(aL(c#W~$b%uJUo=1q3HmH;! z60YmA-As4?aQYyhQyUJ}`>A1{Py>rq^vJbK;0H0%5sYZiE-DBc=Ak`lSTu*bu`WY{ zR}9Gnj%Cpxq=T!{*|)~2>L<)7`_bsfj8bU;0)*aPG)Qw_>yT~3IekbtsB~r0D?Ktd z)(CTTPzFyH@$*(=faeDkEJ68Pz+xH8juE>jtsHIG>|`8mf*n!+HL}=$skIQ0FJumz zn8`TRmc%c4W|BE@KcgZ(1-?)PSd6xQ523)=vx}|Bc0hqUPJ9kgP~sC${mCqm7*zF8 zsombA2lZUJw)?Ok6lF0i+tmV%*j0lfi`r|b!{G#m+YFA_d%MEeIU*%NBMlJcQ|3i2 zyIc)_T^n9xzrhIq8!2em3KO_NJ3krw5IKCA#YutlQGefD**vUMq!n|3ur8=75v<fK zZ>>m=lDgvxV;zShtK=A|G;;hsyAum{obN=J)9Jw=OcjjgOogYh=1OoLtZUXC89A56 z^&>?<*W<^hn{2x;H5-Ct<+o37z1Jj&Y{d6K7hE>mZu3H(Z>%_0SPmV01ZJ&1u2>O> z<wW&T#fani<17z{CNG^O8CeO=1t_(m;;~D7|9(gypI22MpaY`+W{AGZWMwdy`nEYM z?C?GrEUm-XzgKK7XahVku}9^=2p=)iln(qow3b8ZDJlW6H6R|ArkC0E9Fq4;cs=;F zxj25PS)ONR-FoG?v+TQ=NyJP(WJj5Oqo-IvHuO%cvY^+j0<!|rEoTq>U9`qHs)D>^ zO=$=lX`9IOIKJ+Wd?v~_4QiAm=eexM`F-fi#vrz_SG?S*sK90A8(f}uu{A<&#cDd; z&dQguU6AjZ6T9}>{W_hEM%Z*#Yn7lhA7ai=aFbi|SXl)Ve6<9hg#FZe4Pw&KPO|3& zJv9jyNeWVsbX(L1c)#~++V>c$=kH2laI0Z3^e^@sDm=tiK@_&4_*I&)!v`8=iWk26 zIAuUW(Xy4d!gJ9KD8KiM_;q{T_;aV^)0R*RzH8AAEq;ndZcO~iTex`8zVq}p6fe7D z=O)<@25nss{M208&qz@HT?T1=40bvOtT!p4*U+A&+S`q0EDC(+N$+C<t0vz#Q!fh% z(rL><cbn|?$xrrR*9it()3*on-%d$RO|As4A<rl~eRqraen`j!o@n7M!xOcOh-<f0 z2}UkR);+o7r!ozR!D+2={;2n~s9#r{2Ry}XCk_hQ<X2%;OJGf=^2Xa~GN9#i+?`(B z3Vn!;%E1_*;!erymH^Lb2_Hc4WR(=6l+#26c=048hFfb~yU7PZ<5_;W9~Av6@3Nf6 z7Qv=k#{2x=m(g+Q=|G2Ez=x^=aw)$jZaVcRRWep*uEwvrxG#o5GNL~UY3^*{EMWry zMYEr`#-e2)R#N-I_ilI0U=AY8&apK4La|+W(R)xc@Em<j`luPc*^0!ab4xnn%|>@0 ze2m86EC(UcbprawRYrWj=tsWauPqbO&;2nlwKge9&vpKK{(s+1Q|i5@r4Z<dTE)JE zcr-$r+T1|qYNQu4*nS}ONV53`TJh9#4_uI-{i92IroWdQA5%DhYx_<Rp4PAqCCrTn zs8>15afFkc&o)<Y889`%%~|E-I&qtUUPpD+cGh>dSo8<-`Bs@5XaEGb$~7h32i?6% z>uUApu2Zq7AeOIye=I-Y58=@zOacmcG;_71_1+ro9bsSUV016vR^Kpg@4zbhv=w#L z>&uSL#rAAxS7ddDpB$5Ylk0rDRa4sh6X$&S&czk%Stnwl$skLv!$k7Vjg&{1-<4Xx zd8f5W0sRG~Q}OoW0Z>Qlb>4O`6Ziw>P&fDV`d<sIPeUMB{xe*9G11U9iLhO**1Fl_ zgpx^ZJ%;7=-@5w+0}FZ-;MyD=Io!fq=VwOL+hWcXI&u_A=7SL=445ftT<#S3LTy(c z>wZ>+&b2xikdNU`-*GQ|?j4{Ho9JO+3Js$v1>;ii6B=S0zLewOhjN{<Pxivpz8>;+ zCbM#f_tTLwrO1j~(TR(*!y7;J(F%e={|j~6nyu-mQTEQZvz>wb?nzOKA$Svf|9GF9 zs373R8K`L+1Fe-L!`W^z^j7d|=%ho46hD!U@YO|%sQ)44J?M1#AA^H~ILJ-*!2-U< zJx5G#VW;ILPOQI924kDzP@k0ci`$+wwBdvkY4wB;OB-BDhFEtab5?xkBN8S%o4eR? z^3k_br?tPBSlQa2@S4SOjX#J&!8dsm3E>;I^kRe%$iBHkolUNNcQzmcIX5_MrHKB# z=m|1C^EUXlrN-@bBr<x9e!g8j;sm?Xj7}c6GP#@<R!6!cI_Xvg8Yb3HH-xiQ5FA*x z2iI3;7w5VP&tJv+0cH1Y7Ilu)*7OXp`na#rrM|Kf&Df`Uu?eoMxl;FJvpEXCltMQc z<A0anutc%LEoH;DIIu954e|YN&>S*yfrpd|KNs!LGOygwpU5rYr%&<_#=@*JVCY2R z3JnV5*R#43#-`-4BduwKDx=)`--F(H;Ifwdg$TJ7@$+uLQj$%OtvAJJH3(UNdU|QT z#&o@d2ZvTO0U=R66Gr_$!lK~-0DZ|iVN<%Y7wB$uh7JgT!G5vPs<!Yyl2>>*A`#Mq wQ)@9(xo_Px+L(yIpK({D-;$>v8br~<_g56!3YAbvurdf4F2;iQ&<qcQkXaRPzW@LL literal 0 HcmV?d00001 diff --git a/static/images/docs/products/databases/postgresql/monitor.avif b/static/images/docs/products/databases/postgresql/monitor.avif new file mode 100644 index 0000000000000000000000000000000000000000..93e13b873e223ea2e65a9e22516dba794fa08e9f GIT binary patch literal 44865 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 literal 0 HcmV?d00001 diff --git a/static/images/docs/products/databases/postgresql/roles-tab.avif b/static/images/docs/products/databases/postgresql/roles-tab.avif new file mode 100644 index 0000000000000000000000000000000000000000..01b8f19e157d4b4c0495bdd32940d8268de48f40 GIT binary patch literal 26872 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 literal 0 HcmV?d00001 diff --git a/static/images/docs/products/databases/postgresql/settings-compute-tier.avif b/static/images/docs/products/databases/postgresql/settings-compute-tier.avif new file mode 100644 index 0000000000000000000000000000000000000000..cc1f570c7e76f80b6e3828bfbbb7d2985ed2a63a GIT binary patch literal 41167 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�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 literal 0 HcmV?d00001 diff --git a/static/images/docs/products/databases/postgresql/settings-high-availability.avif b/static/images/docs/products/databases/postgresql/settings-high-availability.avif new file mode 100644 index 0000000000000000000000000000000000000000..7dd74d774209e61c6c08a987434e4d5f7d4be331 GIT binary patch literal 38977 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®B6=N3>9sDa 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 literal 0 HcmV?d00001 diff --git a/static/images/docs/products/databases/postgresql/settings-network.avif b/static/images/docs/products/databases/postgresql/settings-network.avif new file mode 100644 index 0000000000000000000000000000000000000000..23fcff820de532021de49ebe97f942eb8fbfae14 GIT binary patch literal 30323 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 G8CTYWFtY3b literal 0 HcmV?d00001 diff --git a/static/images/docs/products/databases/postgresql/settings-pitr.avif b/static/images/docs/products/databases/postgresql/settings-pitr.avif new file mode 100644 index 0000000000000000000000000000000000000000..3e73b5f22c76281a394f80387922fd1591e4aaf8 GIT binary patch literal 31699 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 Z;~psSmF<Wc0Rs(kB|!9j<nsWz{=jXyUuysW literal 0 HcmV?d00001 diff --git a/static/images/docs/products/databases/postgresql/settings.avif b/static/images/docs/products/databases/postgresql/settings.avif new file mode 100644 index 0000000000000000000000000000000000000000..aa6de37d5241760caa12f601a608ab69c99ec927 GIT binary patch literal 32840 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 Wn2L9Wv6wk*YMN_)4{Hi_s@QCh@5m4U literal 0 HcmV?d00001 diff --git a/static/images/docs/products/databases/postgresql/sql-editor.avif b/static/images/docs/products/databases/postgresql/sql-editor.avif new file mode 100644 index 0000000000000000000000000000000000000000..24e982281f9173b251d4e39da1182370c6b82181 GIT binary patch literal 24588 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 literal 0 HcmV?d00001 From 97ba538f6c4d55ce50a7bfafc1eba07fbb7e93a6 Mon Sep 17 00:00:00 2001 From: Atharva Deosthale <atharva.deosthale17@gmail.com> Date: Thu, 9 Jul 2026 00:54:27 +0530 Subject: [PATCH 7/8] Add MySQL native database docs with integrations --- .../products/databases/mysql/+layout.svelte | 125 +- .../products/databases/mysql/+page.markdoc | 101 +- .../databases/mysql/backups/+page.markdoc | 1371 +++++++++++++++++ .../databases/mysql/branches/+page.markdoc | 716 +++++++++ .../mysql/connection-pooling/+page.markdoc | 274 ++++ .../databases/mysql/connections/+page.markdoc | 509 ++++++ .../mysql/high-availability/+page.markdoc | 631 ++++++++ .../mysql/integrations/auth-js/+page.markdoc | 222 +++ .../integrations/better-auth/+page.markdoc | 139 ++ .../mysql/integrations/dbt/+page.markdoc | 113 ++ .../mysql/integrations/django/+page.markdoc | 151 ++ .../mysql/integrations/drivers/+page.markdoc | 225 +++ .../mysql/integrations/drizzle/+page.markdoc | 172 +++ .../mysql/integrations/ef-core/+page.markdoc | 178 +++ .../mysql/integrations/fastapi/+page.markdoc | 193 +++ .../mysql/integrations/gorm/+page.markdoc | 217 +++ .../mysql/integrations/grafana/+page.markdoc | 99 ++ .../mysql/integrations/laravel/+page.markdoc | 215 +++ .../mysql/integrations/metabase/+page.markdoc | 78 + .../mysql/integrations/nextjs/+page.markdoc | 204 +++ .../mysql/integrations/prisma/+page.markdoc | 214 +++ .../mysql/integrations/rails/+page.markdoc | 173 +++ .../mysql/integrations/retool/+page.markdoc | 89 ++ .../integrations/spring-boot/+page.markdoc | 182 +++ .../databases/mysql/maintenance/+page.markdoc | 642 ++++++++ .../databases/mysql/monitoring/+page.markdoc | 215 +++ .../mysql/network-security/+page.markdoc | 500 ++++++ .../databases/mysql/quick-start/+page.markdoc | 104 ++ .../databases/mysql/scaling/+page.markdoc | 649 ++++++++ .../mysql/create-database-specs.avif | Bin 0 -> 32210 bytes .../databases/mysql/create-database-type.avif | Bin 0 -> 38356 bytes .../mysql/dark/create-database-specs.avif | Bin 0 -> 34014 bytes .../mysql/dark/create-database-type.avif | Bin 0 -> 41317 bytes 33 files changed, 8696 insertions(+), 5 deletions(-) create mode 100644 src/routes/docs/products/databases/mysql/backups/+page.markdoc create mode 100644 src/routes/docs/products/databases/mysql/branches/+page.markdoc create mode 100644 src/routes/docs/products/databases/mysql/connection-pooling/+page.markdoc create mode 100644 src/routes/docs/products/databases/mysql/connections/+page.markdoc create mode 100644 src/routes/docs/products/databases/mysql/high-availability/+page.markdoc create mode 100644 src/routes/docs/products/databases/mysql/integrations/auth-js/+page.markdoc create mode 100644 src/routes/docs/products/databases/mysql/integrations/better-auth/+page.markdoc create mode 100644 src/routes/docs/products/databases/mysql/integrations/dbt/+page.markdoc create mode 100644 src/routes/docs/products/databases/mysql/integrations/django/+page.markdoc create mode 100644 src/routes/docs/products/databases/mysql/integrations/drivers/+page.markdoc create mode 100644 src/routes/docs/products/databases/mysql/integrations/drizzle/+page.markdoc create mode 100644 src/routes/docs/products/databases/mysql/integrations/ef-core/+page.markdoc create mode 100644 src/routes/docs/products/databases/mysql/integrations/fastapi/+page.markdoc create mode 100644 src/routes/docs/products/databases/mysql/integrations/gorm/+page.markdoc create mode 100644 src/routes/docs/products/databases/mysql/integrations/grafana/+page.markdoc create mode 100644 src/routes/docs/products/databases/mysql/integrations/laravel/+page.markdoc create mode 100644 src/routes/docs/products/databases/mysql/integrations/metabase/+page.markdoc create mode 100644 src/routes/docs/products/databases/mysql/integrations/nextjs/+page.markdoc create mode 100644 src/routes/docs/products/databases/mysql/integrations/prisma/+page.markdoc create mode 100644 src/routes/docs/products/databases/mysql/integrations/rails/+page.markdoc create mode 100644 src/routes/docs/products/databases/mysql/integrations/retool/+page.markdoc create mode 100644 src/routes/docs/products/databases/mysql/integrations/spring-boot/+page.markdoc create mode 100644 src/routes/docs/products/databases/mysql/maintenance/+page.markdoc create mode 100644 src/routes/docs/products/databases/mysql/monitoring/+page.markdoc create mode 100644 src/routes/docs/products/databases/mysql/network-security/+page.markdoc create mode 100644 src/routes/docs/products/databases/mysql/quick-start/+page.markdoc create mode 100644 src/routes/docs/products/databases/mysql/scaling/+page.markdoc create mode 100644 static/images/docs/products/databases/mysql/create-database-specs.avif create mode 100644 static/images/docs/products/databases/mysql/create-database-type.avif create mode 100644 static/images/docs/products/databases/mysql/dark/create-database-specs.avif create mode 100644 static/images/docs/products/databases/mysql/dark/create-database-type.avif diff --git a/src/routes/docs/products/databases/mysql/+layout.svelte b/src/routes/docs/products/databases/mysql/+layout.svelte index f6fe631eea8..6db5d3b4c4a 100644 --- a/src/routes/docs/products/databases/mysql/+layout.svelte +++ b/src/routes/docs/products/databases/mysql/+layout.svelte @@ -6,7 +6,7 @@ const parent: NavParent = { href: '/docs/products/databases', - label: 'Databases' + label: 'MySQL' }; const navigation: NavTree = [ @@ -16,6 +16,129 @@ { label: 'Overview', href: '/docs/products/databases/mysql' + }, + { + label: 'Quick start', + href: '/docs/products/databases/mysql/quick-start' + } + ] + }, + { + label: 'Connecting', + items: [ + { + label: 'Connections', + href: '/docs/products/databases/mysql/connections' + }, + { + label: 'Connection pooling', + href: '/docs/products/databases/mysql/connection-pooling' + } + ] + }, + { + label: 'Manage', + items: [ + { + label: 'Backups', + href: '/docs/products/databases/mysql/backups' + }, + { + label: 'Branches', + href: '/docs/products/databases/mysql/branches' + }, + { + label: 'High availability', + href: '/docs/products/databases/mysql/high-availability' + }, + { + label: 'Scaling', + href: '/docs/products/databases/mysql/scaling' + }, + { + label: 'Network security', + href: '/docs/products/databases/mysql/network-security' + }, + { + label: 'Monitoring', + href: '/docs/products/databases/mysql/monitoring' + }, + { + label: 'Maintenance', + href: '/docs/products/databases/mysql/maintenance' + } + ] + }, + { + label: 'Integrations', + items: [ + { + label: 'Node.js drivers', + href: '/docs/products/databases/mysql/integrations/drivers' + }, + { + label: 'Prisma', + href: '/docs/products/databases/mysql/integrations/prisma' + }, + { + label: 'Drizzle', + href: '/docs/products/databases/mysql/integrations/drizzle' + }, + { + label: 'Auth.js', + href: '/docs/products/databases/mysql/integrations/auth-js' + }, + { + label: 'Better Auth', + href: '/docs/products/databases/mysql/integrations/better-auth' + }, + { + label: 'Laravel', + href: '/docs/products/databases/mysql/integrations/laravel' + }, + { + label: 'Rails', + href: '/docs/products/databases/mysql/integrations/rails' + }, + { + label: 'Django', + href: '/docs/products/databases/mysql/integrations/django' + }, + { + label: 'FastAPI', + href: '/docs/products/databases/mysql/integrations/fastapi' + }, + { + label: 'Spring Boot', + href: '/docs/products/databases/mysql/integrations/spring-boot' + }, + { + label: 'EF Core', + href: '/docs/products/databases/mysql/integrations/ef-core' + }, + { + label: 'GORM', + href: '/docs/products/databases/mysql/integrations/gorm' + }, + { + label: 'Next.js', + href: '/docs/products/databases/mysql/integrations/nextjs' + }, + { + label: 'dbt', + href: '/docs/products/databases/mysql/integrations/dbt' + }, + { + label: 'Metabase', + href: '/docs/products/databases/mysql/integrations/metabase' + }, + { + label: 'Grafana', + href: '/docs/products/databases/mysql/integrations/grafana' + }, + { + label: 'Retool', + href: '/docs/products/databases/mysql/integrations/retool' } ] } diff --git a/src/routes/docs/products/databases/mysql/+page.markdoc b/src/routes/docs/products/databases/mysql/+page.markdoc index de42e29c3bd..b026e6c750d 100644 --- a/src/routes/docs/products/databases/mysql/+page.markdoc +++ b/src/routes/docs/products/databases/mysql/+page.markdoc @@ -1,11 +1,104 @@ --- layout: article title: MySQL -description: Run a dedicated, native MySQL database provisioned for your project and connect to it directly with standard MySQL clients. +description: Run a native MySQL database provisioned for your project and connect to it directly with standard MySQL clients. --- -Run a dedicated, native MySQL database provisioned for your project. Connect to it directly with standard MySQL clients and tools, with no Appwrite abstraction layer in between. Native databases are available on dedicated infrastructure. +Appwrite native MySQL databases give you a managed MySQL instance provisioned for your project. You pick the compute specification, and Appwrite provisions the engine in your project's region with its own storage, networking, and credentials, exposed through a per-database public hostname secured with TLS. -{% info title="Documentation in progress" %} -Detailed MySQL setup and connection guides are on the way. +Native databases are different from Appwrite databases like [TablesDB](/docs/products/databases/tablesdb), [DocumentsDB](/docs/products/databases/documentsdb), and [VectorsDB](/docs/products/databases/vectorsdb), which are accessed through Appwrite SDKs and platform APIs. A native MySQL database gives you the raw engine. You connect with the `mysql` client or any MySQL driver and use the full feature set of MySQL, with no Appwrite abstraction layer in between. + +{% info title="Looking for Appwrite data APIs?" %} +If you want Appwrite SDKs, platform permissions, and serverless scaling for app data, start with [Appwrite Databases](/docs/products/databases). Native MySQL is for teams who want a managed MySQL engine they can talk to directly with their own ORM, migrations, and drivers. {% /info %} + +# Supported versions {% #versions %} + +Appwrite manages the database container, storage, backups, and networking. You bring the application. + +| Engine | Default version | Other supported versions | Default port | +|------------|-----------------|--------------------------|--------------| +| MySQL | 8.4 | 8.0 | 3306 | + +The version is selected on create and can be upgraded later. Upgrades run online by provisioning a second instance on the new version, streaming data over with logical replication, and moving traffic once replication is caught up. + +A new database starts in a `provisioning` state and becomes `ready` within a few minutes. Large specifications or high-availability configurations take longer to schedule; poll the database status or check the databases list until it reports `ready`. + +# Regions {% #regions %} + +A native database lives in the same region as the project that owns it. There is no per-database region selector. Each database gets a unique hostname in the form `db-<hash>.<region>.appwrite.center`, and data does not leave the region. + +# Feature overview {% #features %} + +{% cards %} +{% cards_item href="/docs/products/databases/mysql/connections" title="Connections" %} +Connect with the `mysql` client or any driver. Credentials are rotatable through the API. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/connection-pooling" title="Connection pooling" %} +Per-database connection pooler with automatic read/write split when high availability is enabled. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/backups" title="Backups" %} +Scheduled backups, manual backups, restores, and point-in-time recovery. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/branches" title="Branches" %} +Spin up an ephemeral copy of your database in seconds from a storage snapshot. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/high-availability" title="High availability" %} +Up to five synchronous, semi-synchronous, or asynchronous replicas with automatic failover. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/scaling" title="Scaling" %} +Resize compute online and grow storage automatically as your data grows. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/network-security" title="Network security" %} +TLS by default, optional IP allowlists, and a dedicated hostname per database. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/monitoring" title="Monitoring" %} +Poll live health, connection, replica, and storage information from your pipelines and monitoring. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/maintenance" title="Maintenance" %} +Maintenance windows, online version upgrades, and pause and resume. +{% /cards_item %} +{% /cards %} + +# Specifications and pricing {% #specifications %} + +Each database runs against one of the following compute specifications, billed monthly: + +| Tier | Specification | CPU | Memory | Storage | Bandwidth | Connections | Price | +|-----------------|----------------|---------|--------|---------|-----------|-------------|---------| +| Starter | `s-1vcpu-1gb` | 1 core | 1 GB | 10 GB | 50 GB | 100 | $10/mo | +| Standard | `s-2vcpu-2gb` | 2 cores | 2 GB | 25 GB | 200 GB | 200 | $20/mo | +| Standard Plus | `s-2vcpu-4gb` | 2 cores | 4 GB | 50 GB | 400 GB | 500 | $49/mo | +| Professional | `s-4vcpu-8gb` | 4 cores | 8 GB | 200 GB | 1 TB | 1,000 | $85/mo | +| Business | `s-4vcpu-16gb` | 4 cores | 16 GB | 500 GB | 2 TB | 2,000 | $160/mo | +| Business Plus | `s-4vcpu-32gb` | 4 cores | 32 GB | 1 TB | 5 TB | 4,000 | $299/mo | +| Enterprise | `s-8vcpu-32gb` | 8 cores | 32 GB | 2 TB | 7.5 TB | 5,000 | $425/mo | +| Enterprise Plus | `s-8vcpu-64gb` | 8 cores | 64 GB | 3 TB | 10 TB | 10,000 | $699/mo | + +The Storage and Bandwidth columns are the monthly allowances included with each tier. Usage beyond them is billed as overage, and optional features are billed as add-ons on top of the tier price: + +| Add-on | Price | +|----------------------------|---------------------------------| +| Storage overage | $0.125 per GB per month | +| Bandwidth overage | $0.08 per GB per month | +| High availability replica | 50% of the tier price, per replica | +| Point-in-time recovery | 20% of the tier price | + +You can [resize between tiers](/docs/products/databases/mysql/scaling) as your workload changes. + +# Limits {% #limits %} + +The following limits apply per database: + +| Limit | Value | +|--------------------------------|-----------------------------------------------------------| +| Databases per project | 10 | +| High availability replicas | 0 - 5 | +| IP allowlist entries | 100 | +| Backup retention | 1 - 365 days | +| Point-in-time recovery window | 1 - 35 days | +| Max simultaneous connections | 10,000 platform cap, lower on smaller specifications | + +# Billing and plan requirements {% #plans %} + +Native databases are available on paid plans, and a payment method must be attached to your organization. Each database is billed by the hour against its [compute specification](#specifications), with separate line items for overages and add-ons. See [pricing](/pricing) for details. diff --git a/src/routes/docs/products/databases/mysql/backups/+page.markdoc b/src/routes/docs/products/databases/mysql/backups/+page.markdoc new file mode 100644 index 00000000000..410eb7980c3 --- /dev/null +++ b/src/routes/docs/products/databases/mysql/backups/+page.markdoc @@ -0,0 +1,1371 @@ +--- +layout: article +title: Backups +description: Scheduled backups, manual backups, restores, and point-in-time recovery for your MySQL database. +--- + +Native databases are backed up automatically. Backups are stored off the database instance and restorable from the API. For finer recovery granularity than scheduled backups, enable point-in-time recovery. + +# Automatic backups {% #automatic %} + +Every database gets a default backup policy when it is provisioned, so you have scheduled backups from day one. You can adjust the default policy, or add more policies with different schedules and retention windows. + +# Backup policies {% #policies %} + +A policy defines a schedule (cron expression) and a retention period in days. Create one with: + +{% multicode %} + +```server-nodejs +import { Client, Mysql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +await mysql.createBackupPolicy({ + databaseId: '<DATABASE_ID>', + policyId: 'hourly', + name: 'Hourly', + schedule: '0 * * * *', + retention: 30, +}); +``` + +```server-deno +import { Client, Mysql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +await mysql.createBackupPolicy({ + databaseId: '<DATABASE_ID>', + policyId: 'hourly', + name: 'Hourly', + schedule: '0 * * * *', + retention: 30, +}); +``` + +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Mysql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$mysql = new Mysql($client); + +$mysql->createBackupPolicy( + databaseId: '<DATABASE_ID>', + policyId: 'hourly', + name: 'Hourly', + schedule: '0 * * * *', + retention: 30, +); +``` + +```server-python +from appwrite.client import Client +from appwrite.services.mysql import Mysql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +mysql = Mysql(client) + +mysql.create_backup_policy( + database_id='<DATABASE_ID>', + policy_id='hourly', + name='Hourly', + schedule='0 * * * *', + retention=30, +) +``` + +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +mysql = Mysql.new(client) + +mysql.create_backup_policy( + database_id: '<DATABASE_ID>', + policy_id: 'hourly', + name: 'Hourly', + schedule: '0 * * * *', + retention: 30, +) +``` + +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Mysql mysql = new Mysql(client); + +await mysql.CreateBackupPolicy( + databaseId: "<DATABASE_ID>", + policyId: "hourly", + name: "Hourly", + schedule: "0 * * * *", + retention: 30 +); +``` + +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Mysql mysql = Mysql(client); + +await mysql.createBackupPolicy( + databaseId: '<DATABASE_ID>', + policyId: 'hourly', + name: 'Hourly', + schedule: '0 * * * *', + retention: 30, +); +``` + +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Mysql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val mysql = Mysql(client) + +mysql.createBackupPolicy( + databaseId = "<DATABASE_ID>", + policyId = "hourly", + name = "Hourly", + schedule = "0 * * * *", + retention = 30, +) +``` + +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let mysql = Mysql(client) + +_ = try await mysql.createBackupPolicy( + databaseId: "<DATABASE_ID>", + policyId: "hourly", + name: "Hourly", + schedule: "0 * * * *", + retention: 30 +) +``` + +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewMysql(client) + + _, err := service.CreateBackupPolicy("<DATABASE_ID>", "hourly", "Hourly", "0 * * * *", 30) + if err != nil { + panic(err) + } +} +``` + +```server-rust +use appwrite::client::Client; +use appwrite::services::mysql::Mysql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let mysql = Mysql::new(&client); + + mysql.create_backup_policy("<DATABASE_ID>", "hourly", "Hourly", "0 * * * *", 30, None, None).await?; + + Ok(()) +} +``` + +```bash +curl -X POST \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <API_KEY>" \ + -H "Content-Type: application/json" \ + -d '{ + "policyId": "hourly", + "name": "Hourly", + "schedule": "0 * * * *", + "retention": 30 + }' \ + https://<REGION>.cloud.appwrite.io/v1/mysql/<DATABASE_ID>/backups/policies +``` + +{% /multicode %} + +| Parameter | Value | Description | +| ----------- | ----------------------- | ------------------------------------------ | +| `policyId` | custom ID or `unique()` | Policy identifier | +| `name` | text | Display name | +| `schedule` | cron expression | When backups run, for example `0 3 * * *` | +| `retention` | 1 - 365 days | How long backups from this policy are kept | + +List, update, and delete policies with `listBackupPolicies`, `updateBackupPolicy`, and `deleteBackupPolicy`. The number of policies you can create depends on your plan. + +# Manual backups {% #manual %} + +Take an on-demand backup before a risky change: + +{% multicode %} + +```server-nodejs +import { Client, Mysql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +const backup = await mysql.createBackup({ + databaseId: '<DATABASE_ID>', +}); +``` + +```server-deno +import { Client, Mysql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +const backup = await mysql.createBackup({ + databaseId: '<DATABASE_ID>', +}); +``` + +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Mysql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$mysql = new Mysql($client); + +$backup = $mysql->createBackup( + databaseId: '<DATABASE_ID>', +); +``` + +```server-python +from appwrite.client import Client +from appwrite.services.mysql import Mysql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +mysql = Mysql(client) + +backup = mysql.create_backup( + database_id='<DATABASE_ID>', +) +``` + +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +mysql = Mysql.new(client) + +backup = mysql.create_backup( + database_id: '<DATABASE_ID>', +) +``` + +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Mysql mysql = new Mysql(client); + +var backup = await mysql.CreateBackup( + databaseId: "<DATABASE_ID>" +); +``` + +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Mysql mysql = Mysql(client); + +final backup = await mysql.createBackup( + databaseId: '<DATABASE_ID>', +); +``` + +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Mysql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val mysql = Mysql(client) + +val backup = mysql.createBackup( + databaseId = "<DATABASE_ID>", +) +``` + +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let mysql = Mysql(client) + +let backup = try await mysql.createBackup( + databaseId: "<DATABASE_ID>" +) +``` + +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewMysql(client) + + result, err := service.CreateBackup("<DATABASE_ID>") + if err != nil { + panic(err) + } + _ = result +} +``` + +```server-rust +use appwrite::client::Client; +use appwrite::services::mysql::Mysql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let mysql = Mysql::new(&client); + + let backup = mysql.create_backup("<DATABASE_ID>", None).await?; + + Ok(()) +} +``` + +```bash +curl -X POST \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <API_KEY>" \ + https://<REGION>.cloud.appwrite.io/v1/mysql/<DATABASE_ID>/backups +``` + +{% /multicode %} + +The backup runs asynchronously with status `pending` until it completes. List backups and check their status with `listBackups`, or fetch one with `getBackup`. + +# Restore from a backup {% #restore %} + +Restoring replaces the database's current data with the backup's contents. The database status moves to `restoring` and returns to `ready` when the restore completes; connections are unavailable during the restore. + +{% multicode %} + +```server-nodejs +import { Client, Mysql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +await mysql.createRestoration({ + databaseId: '<DATABASE_ID>', + type: 'backup', + backupId: '<BACKUP_ID>', +}); +``` + +```server-deno +import { Client, Mysql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +await mysql.createRestoration({ + databaseId: '<DATABASE_ID>', + type: 'backup', + backupId: '<BACKUP_ID>', +}); +``` + +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Mysql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$mysql = new Mysql($client); + +$mysql->createRestoration( + databaseId: '<DATABASE_ID>', + type: 'backup', + backupId: '<BACKUP_ID>', +); +``` + +```server-python +from appwrite.client import Client +from appwrite.services.mysql import Mysql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +mysql = Mysql(client) + +mysql.create_restoration( + database_id='<DATABASE_ID>', + type='backup', + backup_id='<BACKUP_ID>', +) +``` + +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +mysql = Mysql.new(client) + +mysql.create_restoration( + database_id: '<DATABASE_ID>', + type: 'backup', + backup_id: '<BACKUP_ID>', +) +``` + +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Mysql mysql = new Mysql(client); + +await mysql.CreateRestoration( + databaseId: "<DATABASE_ID>", + type: "backup", + backupId: "<BACKUP_ID>" +); +``` + +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Mysql mysql = Mysql(client); + +await mysql.createRestoration( + databaseId: '<DATABASE_ID>', + type: 'backup', + backupId: '<BACKUP_ID>', +); +``` + +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Mysql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val mysql = Mysql(client) + +mysql.createRestoration( + databaseId = "<DATABASE_ID>", + type = "backup", + backupId = "<BACKUP_ID>", +) +``` + +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let mysql = Mysql(client) + +_ = try await mysql.createRestoration( + databaseId: "<DATABASE_ID>", + type: "backup", + backupId: "<BACKUP_ID>" +) +``` + +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" + "github.com/appwrite/sdk-for-go/mysql" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewMysql(client) + + _, err := service.CreateRestoration( + "<DATABASE_ID>", + mysql.WithCreateRestorationType("backup"), + mysql.WithCreateRestorationBackupId("<BACKUP_ID>"), + ) + if err != nil { + panic(err) + } +} +``` + +```server-rust +use appwrite::client::Client; +use appwrite::services::mysql::Mysql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let mysql = Mysql::new(&client); + + mysql.create_restoration("<DATABASE_ID>", Some("backup"), Some("<BACKUP_ID>"), None).await?; + + Ok(()) +} +``` + +```bash +curl -X POST \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <API_KEY>" \ + -H "Content-Type: application/json" \ + -d '{ + "type": "backup", + "backupId": "<BACKUP_ID>" + }' \ + https://<REGION>.cloud.appwrite.io/v1/mysql/<DATABASE_ID>/restorations +``` + +{% /multicode %} + +Track progress with `getRestoration` or the database status. + +{% info title="Restores overwrite current data" %} +Everything written after the backup was taken is lost when you restore it. If you need the current state too, take a manual backup first, or use a [branch](/docs/products/databases/mysql/branches) to inspect data without touching the live database. +{% /info %} + +# Point-in-time recovery {% #pitr %} + +Scheduled backups recover to fixed snapshots. Point-in-time recovery (PITR) continuously archives the binary log, so you can restore to any moment inside the retention window, for example the second before a bad migration ran. + +Enable PITR when creating the database, or through the API: + +{% multicode %} + +```server-nodejs +import { Client, Mysql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +await mysql.update({ + databaseId: '<DATABASE_ID>', + pitr: true, + pitrRetentionDays: 7, +}); +``` + +```server-deno +import { Client, Mysql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +await mysql.update({ + databaseId: '<DATABASE_ID>', + pitr: true, + pitrRetentionDays: 7, +}); +``` + +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Mysql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$mysql = new Mysql($client); + +$mysql->update( + databaseId: '<DATABASE_ID>', + pitr: true, + pitrRetentionDays: 7, +); +``` + +```server-python +from appwrite.client import Client +from appwrite.services.mysql import Mysql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +mysql = Mysql(client) + +mysql.update( + database_id='<DATABASE_ID>', + pitr=True, + pitr_retention_days=7, +) +``` + +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +mysql = Mysql.new(client) + +mysql.update( + database_id: '<DATABASE_ID>', + pitr: true, + pitr_retention_days: 7, +) +``` + +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Mysql mysql = new Mysql(client); + +await mysql.Update( + databaseId: "<DATABASE_ID>", + pitr: true, + pitrRetentionDays: 7 +); +``` + +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Mysql mysql = Mysql(client); + +await mysql.update( + databaseId: '<DATABASE_ID>', + pitr: true, + pitrRetentionDays: 7, +); +``` + +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Mysql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val mysql = Mysql(client) + +mysql.update( + databaseId = "<DATABASE_ID>", + pitr = true, + pitrRetentionDays = 7, +) +``` + +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let mysql = Mysql(client) + +_ = try await mysql.update( + databaseId: "<DATABASE_ID>", + pitr: true, + pitrRetentionDays: 7 +) +``` + +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" + "github.com/appwrite/sdk-for-go/mysql" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewMysql(client) + + _, err := service.Update( + "<DATABASE_ID>", + mysql.WithUpdatePitr(true), + mysql.WithUpdatePitrRetentionDays(7), + ) + if err != nil { + panic(err) + } +} +``` + +```server-rust +use appwrite::client::Client; +use appwrite::services::mysql::Mysql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let mysql = Mysql::new(&client); + + mysql.update("<DATABASE_ID>", None, None, None, None, None, None, None, None, Some(true), Some(7), None, None, None, None, None, None, None, None, None, None).await?; + + Ok(()) +} +``` + +```bash +curl -X PATCH \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <API_KEY>" \ + -H "Content-Type: application/json" \ + -d '{ + "pitr": true, + "pitrRetentionDays": 7 + }' \ + https://<REGION>.cloud.appwrite.io/v1/mysql/<DATABASE_ID> +``` + +{% /multicode %} + +`pitrRetentionDays` accepts 1 to 35 days. PITR is billed as an add-on on top of your specification; see [pricing](/pricing). + +## Check the recovery window {% #pitr-windows %} + +You can retrieve the time ranges you can restore to. Right after enabling PITR, no recovery window is available yet; the window opens once continuous archiving has captured its first segment. + +{% multicode %} + +```server-nodejs +import { Client, Mysql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +const windows = await mysql.getPitr({ + databaseId: '<DATABASE_ID>', +}); +``` + +```server-deno +import { Client, Mysql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +const windows = await mysql.getPitr({ + databaseId: '<DATABASE_ID>', +}); +``` + +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Mysql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$mysql = new Mysql($client); + +$windows = $mysql->getPitr( + databaseId: '<DATABASE_ID>', +); +``` + +```server-python +from appwrite.client import Client +from appwrite.services.mysql import Mysql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +mysql = Mysql(client) + +windows = mysql.get_pitr( + database_id='<DATABASE_ID>', +) +``` + +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +mysql = Mysql.new(client) + +windows = mysql.get_pitr( + database_id: '<DATABASE_ID>', +) +``` + +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Mysql mysql = new Mysql(client); + +var windows = await mysql.GetPitr( + databaseId: "<DATABASE_ID>" +); +``` + +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Mysql mysql = Mysql(client); + +final windows = await mysql.getPitr( + databaseId: '<DATABASE_ID>', +); +``` + +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Mysql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val mysql = Mysql(client) + +val windows = mysql.getPitr( + databaseId = "<DATABASE_ID>", +) +``` + +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let mysql = Mysql(client) + +let windows = try await mysql.getPitr( + databaseId: "<DATABASE_ID>" +) +``` + +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewMysql(client) + + result, err := service.GetPitr("<DATABASE_ID>") + if err != nil { + panic(err) + } + _ = result +} +``` + +```server-rust +use appwrite::client::Client; +use appwrite::services::mysql::Mysql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let mysql = Mysql::new(&client); + + let windows = mysql.get_pitr("<DATABASE_ID>").await?; + + Ok(()) +} +``` + +```bash +curl -X GET \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <API_KEY>" \ + https://<REGION>.cloud.appwrite.io/v1/mysql/<DATABASE_ID>/pitr +``` + +{% /multicode %} + +## Restore to a point in time {% #pitr-restore %} + +Pass a Unix timestamp inside the recovery window: + +{% multicode %} + +```server-nodejs +import { Client, Mysql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +await mysql.createRestoration({ + databaseId: '<DATABASE_ID>', + type: 'pitr', + targetTime: 1767225600, +}); +``` + +```server-deno +import { Client, Mysql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +await mysql.createRestoration({ + databaseId: '<DATABASE_ID>', + type: 'pitr', + targetTime: 1767225600, +}); +``` + +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Mysql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$mysql = new Mysql($client); + +$mysql->createRestoration( + databaseId: '<DATABASE_ID>', + type: 'pitr', + targetTime: 1767225600, +); +``` + +```server-python +from appwrite.client import Client +from appwrite.services.mysql import Mysql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +mysql = Mysql(client) + +mysql.create_restoration( + database_id='<DATABASE_ID>', + type='pitr', + target_time=1767225600, +) +``` + +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +mysql = Mysql.new(client) + +mysql.create_restoration( + database_id: '<DATABASE_ID>', + type: 'pitr', + target_time: 1767225600, +) +``` + +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Mysql mysql = new Mysql(client); + +await mysql.CreateRestoration( + databaseId: "<DATABASE_ID>", + type: "pitr", + targetTime: 1767225600 +); +``` + +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Mysql mysql = Mysql(client); + +await mysql.createRestoration( + databaseId: '<DATABASE_ID>', + type: 'pitr', + targetTime: 1767225600, +); +``` + +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Mysql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val mysql = Mysql(client) + +mysql.createRestoration( + databaseId = "<DATABASE_ID>", + type = "pitr", + targetTime = 1767225600, +) +``` + +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let mysql = Mysql(client) + +_ = try await mysql.createRestoration( + databaseId: "<DATABASE_ID>", + type: "pitr", + targetTime: 1767225600 +) +``` + +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" + "github.com/appwrite/sdk-for-go/mysql" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewMysql(client) + + _, err := service.CreateRestoration( + "<DATABASE_ID>", + mysql.WithCreateRestorationType("pitr"), + mysql.WithCreateRestorationTargetTime(1767225600), + ) + if err != nil { + panic(err) + } +} +``` + +```server-rust +use appwrite::client::Client; +use appwrite::services::mysql::Mysql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let mysql = Mysql::new(&client); + + mysql.create_restoration("<DATABASE_ID>", Some("pitr"), None, Some(1767225600)).await?; + + Ok(()) +} +``` + +```bash +curl -X POST \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <API_KEY>" \ + -H "Content-Type: application/json" \ + -d '{ + "type": "pitr", + "targetTime": 1767225600 + }' \ + https://<REGION>.cloud.appwrite.io/v1/mysql/<DATABASE_ID>/restorations +``` + +{% /multicode %} + +Like a backup restore, a PITR restore is in-place: the database is unavailable while restoring and everything after the target time is discarded. + +# Limits {% #limits %} + +| Limit | Value | +| ---------------- | -------------- | +| Backup retention | 1 - 365 days | +| PITR retention | 1 - 35 days | +| Backup policies | Plan-dependent | diff --git a/src/routes/docs/products/databases/mysql/branches/+page.markdoc b/src/routes/docs/products/databases/mysql/branches/+page.markdoc new file mode 100644 index 00000000000..2b897b0430e --- /dev/null +++ b/src/routes/docs/products/databases/mysql/branches/+page.markdoc @@ -0,0 +1,716 @@ +--- +layout: article +title: Branches +description: Spin up an ephemeral, isolated copy of your MySQL database in seconds from a storage snapshot. Use branches for previews, migrations, and testing. +--- + +A branch is a short-lived, isolated copy of your database. It has its own hostname and reuses the parent's credentials, because it is a snapshot copy of the parent's storage volume taken at a point in time. Branches are not replicas: once created, they diverge from the parent and never sync back. + +{% info title="Branches do not merge back" %} +There is no branch merge operation. Use a branch to validate a migration, data repair, or application change, then intentionally cut application traffic over to the validated database or copy the data you want back with engine-native tools. Appwrite does not reconcile two diverged database histories for you. +{% /info %} + +Use cases: + +- **Preview environments**: one branch per pull request, destroyed when the PR closes +- **Test migrations**: apply a destructive `ALTER` against the branch first, observe the behavior, then run it against the source +- **Reproduce a bug**: branch the database, attach a debugger, throw the branch away when done +- **Heavy analytical queries**: `EXPLAIN ANALYZE` experiments against a branch cannot slow down the primary + +# How it works {% #how %} + +Creating a branch takes a fast `CHECKPOINT` on the parent, snapshots the parent's storage volume with a near-instant copy-on-write operation, and provisions a branch instance from the snapshot on the same engine version with its own isolated storage. Branch compute is fixed and lightweight, enough to validate a change rather than carry production load, and is not configurable. The parent and the branch share storage at the moment of branching; storage cost grows as the two diverge. + +# Create a branch {% #create %} + +{% multicode %} + +```server-nodejs +import { Client, Mysql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +await mysql.createBranch({ + databaseId: '<DATABASE_ID>', + branchId: 'preview', + ttl: 86400, +}); +``` + +```server-deno +import { Client, Mysql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +await mysql.createBranch({ + databaseId: '<DATABASE_ID>', + branchId: 'preview', + ttl: 86400, +}); +``` + +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Mysql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$mysql = new Mysql($client); + +$mysql->createBranch( + databaseId: '<DATABASE_ID>', + branchId: 'preview', + ttl: 86400, +); +``` + +```server-python +from appwrite.client import Client +from appwrite.services.mysql import Mysql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +mysql = Mysql(client) + +mysql.create_branch( + database_id='<DATABASE_ID>', + branch_id='preview', + ttl=86400, +) +``` + +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +mysql = Mysql.new(client) + +mysql.create_branch( + database_id: '<DATABASE_ID>', + branch_id: 'preview', + ttl: 86400, +) +``` + +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Mysql mysql = new Mysql(client); + +await mysql.CreateBranch( + databaseId: "<DATABASE_ID>", + branchId: "preview", + ttl: 86400 +); +``` + +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Mysql mysql = Mysql(client); + +await mysql.createBranch( + databaseId: '<DATABASE_ID>', + branchId: 'preview', + ttl: 86400, +); +``` + +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Mysql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val mysql = Mysql(client) + +mysql.createBranch( + databaseId = "<DATABASE_ID>", + branchId = "preview", + ttl = 86400, +) +``` + +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let mysql = Mysql(client) + +_ = try await mysql.createBranch( + databaseId: "<DATABASE_ID>", + branchId: "preview", + ttl: 86400 +) +``` + +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" + "github.com/appwrite/sdk-for-go/mysql" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewMysql(client) + + _, err := service.CreateBranch( + "<DATABASE_ID>", + mysql.WithCreateBranchBranchId("preview"), + mysql.WithCreateBranchTtl(86400), + ) + if err != nil { + panic(err) + } +} +``` + +```server-rust +use appwrite::client::Client; +use appwrite::services::mysql::Mysql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let mysql = Mysql::new(&client); + + mysql.create_branch("<DATABASE_ID>", Some("preview"), Some(86400)).await?; + + Ok(()) +} +``` + +```bash +curl -X POST \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <YOUR_API_KEY>" \ + -H "Content-Type: application/json" \ + -d '{ + "branchId": "preview", + "ttl": 86400 + }' \ + https://<REGION>.cloud.appwrite.io/v1/mysql/<DATABASE_ID>/branches +``` + +{% /multicode %} + +Both fields are optional: + +| Field | Default | Purpose | +| ---------- | ------------------ | ------------------------------------------------------------------- | +| `branchId` | auto-generated | Custom ID (`a-z`, `A-Z`, `0-9`, `.`, `-`, `_`, max 36 chars) | +| `ttl` | `86400` (24 hours) | Lifetime in seconds before the branch expires (min 300, max 604800) | + +The call is asynchronous and returns immediately while the branch provisions in the background. When the TTL elapses, the branch and its storage are removed automatically. + +# List branches and connect {% #list %} + +Each entry carries its metadata and connection details, so there is no separate credentials call: + +{% multicode %} + +```server-nodejs +import { Client, Mysql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +const branches = await mysql.listBranches({ + databaseId: '<DATABASE_ID>', +}); +``` + +```server-deno +import { Client, Mysql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +const branches = await mysql.listBranches({ + databaseId: '<DATABASE_ID>', +}); +``` + +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Mysql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$mysql = new Mysql($client); + +$branches = $mysql->listBranches( + databaseId: '<DATABASE_ID>', +); +``` + +```server-python +from appwrite.client import Client +from appwrite.services.mysql import Mysql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +mysql = Mysql(client) + +branches = mysql.list_branches( + database_id='<DATABASE_ID>', +) +``` + +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +mysql = Mysql.new(client) + +branches = mysql.list_branches( + database_id: '<DATABASE_ID>', +) +``` + +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Mysql mysql = new Mysql(client); + +var branches = await mysql.ListBranches( + databaseId: "<DATABASE_ID>" +); +``` + +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Mysql mysql = Mysql(client); + +final branches = await mysql.listBranches( + databaseId: '<DATABASE_ID>', +); +``` + +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Mysql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val mysql = Mysql(client) + +val branches = mysql.listBranches( + databaseId = "<DATABASE_ID>", +) +``` + +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let mysql = Mysql(client) + +let branches = try await mysql.listBranches( + databaseId: "<DATABASE_ID>" +) +``` + +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewMysql(client) + + result, err := service.ListBranches("<DATABASE_ID>") + if err != nil { + panic(err) + } + _ = result +} +``` + +```server-rust +use appwrite::client::Client; +use appwrite::services::mysql::Mysql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let mysql = Mysql::new(&client); + + let branches = mysql.list_branches("<DATABASE_ID>").await?; + + Ok(()) +} +``` + +```bash +curl -X GET \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <YOUR_API_KEY>" \ + https://<REGION>.cloud.appwrite.io/v1/mysql/<DATABASE_ID>/branches +``` + +{% /multicode %} + +A branch gets its own hostname, and reuses the parent's username and password because it is a snapshot copy of the parent's storage. The port is the standard `3306`; branches have no connection pooler. Connect with the branch's `connectionString` straight from the response: + +```bash +mysql --defaults-extra-file=<(printf '[client]\npassword=%s\n' "$BRANCH_PASSWORD") -h <branch host> -P 3306 -u admin -D <branch database> +``` + +# Delete a branch {% #delete %} + +Deleting a branch removes the branch's instance, its storage volume, and the underlying snapshot. There is no soft delete: once the branch is gone, the data is gone. + +{% multicode %} + +```server-nodejs +import { Client, Mysql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +await mysql.deleteBranch({ + databaseId: '<DATABASE_ID>', + branchId: 'preview', +}); +``` + +```server-deno +import { Client, Mysql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +await mysql.deleteBranch({ + databaseId: '<DATABASE_ID>', + branchId: 'preview', +}); +``` + +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Mysql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$mysql = new Mysql($client); + +$mysql->deleteBranch( + databaseId: '<DATABASE_ID>', + branchId: 'preview', +); +``` + +```server-python +from appwrite.client import Client +from appwrite.services.mysql import Mysql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +mysql = Mysql(client) + +mysql.delete_branch( + database_id='<DATABASE_ID>', + branch_id='preview', +) +``` + +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +mysql = Mysql.new(client) + +mysql.delete_branch( + database_id: '<DATABASE_ID>', + branch_id: 'preview', +) +``` + +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Mysql mysql = new Mysql(client); + +await mysql.DeleteBranch( + databaseId: "<DATABASE_ID>", + branchId: "preview" +); +``` + +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Mysql mysql = Mysql(client); + +await mysql.deleteBranch( + databaseId: '<DATABASE_ID>', + branchId: 'preview', +); +``` + +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Mysql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val mysql = Mysql(client) + +mysql.deleteBranch( + databaseId = "<DATABASE_ID>", + branchId = "preview", +) +``` + +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let mysql = Mysql(client) + +_ = try await mysql.deleteBranch( + databaseId: "<DATABASE_ID>", + branchId: "preview" +) +``` + +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewMysql(client) + + _, err := service.DeleteBranch("<DATABASE_ID>", "preview") + if err != nil { + panic(err) + } +} +``` + +```server-rust +use appwrite::client::Client; +use appwrite::services::mysql::Mysql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let mysql = Mysql::new(&client); + + mysql.delete_branch("<DATABASE_ID>", "preview").await?; + + Ok(()) +} +``` + +```bash +curl -X DELETE \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <YOUR_API_KEY>" \ + https://<REGION>.cloud.appwrite.io/v1/mysql/<DATABASE_ID>/branches/preview +``` + +{% /multicode %} + +# Billing {% #billing %} + +A branch runs on fixed, lightweight compute, so its cost is dominated by storage. The snapshot is free at the moment of branching; storage cost accumulates as the branch's data diverges from the parent. There is no separate branch line item, branches roll into your regular database storage and compute totals. + +# Use case: per-PR preview database {% #ci-example %} + +A CI pipeline that branches on every pull request and tears down on close: + +```yaml +name: preview-database + +on: + pull_request: + types: [opened, reopened, closed] + +jobs: + branch: + if: github.event.action != 'closed' + runs-on: ubuntu-latest + steps: + - name: Create branch + run: | + curl -X POST \ + -H "X-Appwrite-Project: ${{ vars.APPWRITE_PROJECT_ID }}" \ + -H "X-Appwrite-Key: ${{ secrets.APPWRITE_API_KEY }}" \ + -H "Content-Type: application/json" \ + -d '{"branchId": "pr-${{ github.event.number }}", "ttl": 604800}' \ + https://<REGION>.cloud.appwrite.io/v1/mysql/${{ vars.DATABASE_ID }}/branches || true + + teardown: + if: github.event.action == 'closed' + runs-on: ubuntu-latest + steps: + - name: Delete branch + run: | + curl -X DELETE \ + -H "X-Appwrite-Project: ${{ vars.APPWRITE_PROJECT_ID }}" \ + -H "X-Appwrite-Key: ${{ secrets.APPWRITE_API_KEY }}" \ + https://<REGION>.cloud.appwrite.io/v1/mysql/${{ vars.DATABASE_ID }}/branches/pr-${{ github.event.number }} +``` + +The `|| true` on the create call makes the workflow idempotent: if the branch already exists, the call is a no-op. diff --git a/src/routes/docs/products/databases/mysql/connection-pooling/+page.markdoc b/src/routes/docs/products/databases/mysql/connection-pooling/+page.markdoc new file mode 100644 index 00000000000..9a2719a9239 --- /dev/null +++ b/src/routes/docs/products/databases/mysql/connection-pooling/+page.markdoc @@ -0,0 +1,274 @@ +--- +layout: article +title: Connection pooling +description: Configure the per-database connection pooler to serve many short-lived clients, with automatic read/write splitting when high availability is enabled. +--- + +MySQL creates one backend process per connection, which makes each connection relatively expensive. Serverless functions, edge runtimes, and horizontally scaled application servers can easily exhaust the connection limit of your specification. The connection pooler sits in front of your database and multiplexes many client connections onto a small pool of server connections. + +The pooler runs next to your database and is reachable on port `6033` on the same hostname. Your application connects to the pooler exactly like it would connect to MySQL directly, same credentials, same TLS. The pooler is available on specifications that run on dedicated compute; the smallest specifications run on shared capacity and do not include it. + +# Pool modes {% #modes %} + +| Mode | Behavior | Use for | +|---------------|-----------------------------------------------------------------------------|------------------------------------------------| +| `transaction` | A server connection is assigned for the duration of a transaction, then returned to the pool | Serverless and most applications (default) | +| `session` | A server connection is held for the entire client session | Session-level features: server-side prepared statements, user variables, temporary tables | + +Transaction mode gives the highest connection multiplexing but does not support session-level state. If your framework relies on session state such as server-side prepared statements or temporary tables, use session mode. + +# Configure the pooler {% #configure %} + +Read the current pooler configuration with `getPooler`, and tune the pool mode and sizes with `updatePooler`. All parameters are optional; omitted values keep their current setting. + +{% multicode %} +```server-nodejs +import { Client, Mysql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +const pooler = await mysql.updatePooler({ + databaseId: '<DATABASE_ID>', + mode: 'transaction', + maxConnections: 500, + defaultPoolSize: 25, +}); +``` +```server-deno +import { Client, Mysql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +const pooler = await mysql.updatePooler({ + databaseId: '<DATABASE_ID>', + mode: 'transaction', + maxConnections: 500, + defaultPoolSize: 25, +}); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Mysql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$mysql = new Mysql($client); + +$pooler = $mysql->updatePooler( + databaseId: '<DATABASE_ID>', + mode: 'transaction', + maxConnections: 500, + defaultPoolSize: 25, +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.mysql import Mysql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +mysql = Mysql(client) + +pooler = mysql.update_pooler( + database_id='<DATABASE_ID>', + mode='transaction', + max_connections=500, + default_pool_size=25, +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +mysql = Mysql.new(client) + +pooler = mysql.update_pooler( + database_id: '<DATABASE_ID>', + mode: 'transaction', + max_connections: 500, + default_pool_size: 25, +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Mysql mysql = new Mysql(client); + +var pooler = await mysql.UpdatePooler( + databaseId: "<DATABASE_ID>", + mode: "transaction", + maxConnections: 500, + defaultPoolSize: 25 +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Mysql mysql = Mysql(client); + +final pooler = await mysql.updatePooler( + databaseId: '<DATABASE_ID>', + mode: 'transaction', + maxConnections: 500, + defaultPoolSize: 25, +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Mysql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val mysql = Mysql(client) + +val pooler = mysql.updatePooler( + databaseId = "<DATABASE_ID>", + mode = "transaction", + maxConnections = 500, + defaultPoolSize = 25, +) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let mysql = Mysql(client) + +let pooler = try await mysql.updatePooler( + databaseId: "<DATABASE_ID>", + mode: "transaction", + maxConnections: 500, + defaultPoolSize: 25 +) +``` +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" + "github.com/appwrite/sdk-for-go/mysql" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + mysqlService := appwrite.NewMysql(client) + + result, err := mysqlService.UpdatePooler( + "<DATABASE_ID>", + mysql.WithUpdatePoolerMode("transaction"), + mysql.WithUpdatePoolerMaxConnections(500), + mysql.WithUpdatePoolerDefaultPoolSize(25), + ) + if err != nil { + panic(err) + } + _ = result +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::Mysql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let mysql = Mysql::new(&client); + + let pooler = mysql.update_pooler("<DATABASE_ID>", Some("transaction"), Some(500), Some(25), None, None, None, None, None).await?; + + Ok(()) +} +``` +```bash +curl -X PATCH \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <YOUR_API_KEY>" \ + -H "Content-Type: application/json" \ + -d '{ + "mode": "transaction", + "maxConnections": 500, + "defaultPoolSize": 25 + }' \ + https://<REGION>.cloud.appwrite.io/v1/mysql/<DATABASE_ID>/pooler +``` +{% /multicode %} + +| Parameter | Range | Description | +|----------------------|----------------|--------------------------------------------------------------------------------| +| `mode` | `transaction`, `session` | How long a server connection stays assigned to a client | +| `maxConnections` | 10 - 10,000 | Maximum pooled client connections. Cannot exceed the connection cap of your specification | +| `defaultPoolSize` | 1 - 1,000 | Server connections per user in the pool | +| `readWriteSplitting` | boolean | Route `SELECT`s to replicas, writes and locked reads to the primary. Defaults to on when high availability is enabled | + +# Connect through the pooler {% #connect %} + +Take your normal connection string and change the port to `6033`: + +```bash +mysql://admin:<password>@db-<hash>.<region>.appwrite.center:6033/<database> +``` + +Point your application's runtime traffic at the pooler port. Keep migrations and long-lived administrative sessions on the direct port `3306`, schema changes and tools like `mysqldump` expect session semantics and can misbehave in transaction mode. + +# Read/write splitting {% #read-write-splitting %} + +When [high availability](/docs/products/databases/mysql/high-availability) is enabled, the pooler can route read-only statements to replicas and everything else to the primary. `SELECT ... FOR UPDATE` and statements inside explicit transactions go to the primary. Replicas replicate asynchronously by default, so a read that immediately follows a write can be stale; use `sync` or `quorum` replication mode if you need read-your-writes consistency through the pooler. + +# Sizing guidance {% #sizing %} + +A useful starting point for `defaultPoolSize` is `4 x CPU cores` of your specification, and it rarely helps to go above your specification's connection cap divided by the number of databases sharing the workload. Watch the connection metrics and increase the pool only when clients queue for a connection. + +# When not to use the pooler {% #when-not %} + +Skip the pooler when you have a small, fixed number of long-lived application servers that each maintain their own driver-level pool, and their combined connection count fits comfortably in your specification's limit. Adding a pooler in that setup only adds a hop. diff --git a/src/routes/docs/products/databases/mysql/connections/+page.markdoc b/src/routes/docs/products/databases/mysql/connections/+page.markdoc new file mode 100644 index 00000000000..a8556130322 --- /dev/null +++ b/src/routes/docs/products/databases/mysql/connections/+page.markdoc @@ -0,0 +1,509 @@ +--- +layout: article +title: Connections +description: Connect to your MySQL database with the mysql client or any standard driver. Retrieve connection details and rotate the primary password. +--- + +A native MySQL database exposes a MySQL endpoint over TLS. You connect to it the same way you would connect to any MySQL server: with the `mysql` client, any driver in any language, or any ORM. + +# Get connection details with the API {% #credentials %} + +The connection details are returned on the database object itself. Fetch the database with an API key that has the `databases.read` scope: + +{% multicode %} +```server-nodejs +import { Client, Mysql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +const database = await mysql.get({ + databaseId: '<DATABASE_ID>', +}); + +console.log(database.connectionString); +``` +```server-deno +import { Client, Mysql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +const database = await mysql.get({ + databaseId: '<DATABASE_ID>', +}); + +console.log(database.connectionString); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Mysql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$mysql = new Mysql($client); + +$database = $mysql->get(databaseId: '<DATABASE_ID>'); + +echo $database['connectionString']; +``` +```server-python +from appwrite.client import Client +from appwrite.services.mysql import Mysql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +mysql = Mysql(client) + +database = mysql.get(database_id='<DATABASE_ID>') + +print(database.connection_string) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +mysql = Mysql.new(client) + +database = mysql.get(database_id: '<DATABASE_ID>') + +puts database.connection_string +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Mysql mysql = new Mysql(client); + +var database = await mysql.Get(databaseId: "<DATABASE_ID>"); + +Console.WriteLine(database.ConnectionString); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Mysql mysql = Mysql(client); + +final database = await mysql.get( + databaseId: '<DATABASE_ID>', +); + +print(database.connectionString); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Mysql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val mysql = Mysql(client) + +val database = mysql.get( + databaseId = "<DATABASE_ID>", +) + +println(database.connectionString) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let mysql = Mysql(client) + +let database = try await mysql.get( + databaseId: "<DATABASE_ID>" +) + +print(database.connectionString) +``` +```server-go +package main + +import ( + "fmt" + + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + mysql := appwrite.NewMysql(client) + + database, err := mysql.Get("<DATABASE_ID>") + if err != nil { + panic(err) + } + fmt.Println(database.ConnectionString) +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::mysql::Mysql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let mysql = Mysql::new(&client); + + let database = mysql.get("<DATABASE_ID>").await?; + + println!("{}", database.connection_string); + + Ok(()) +} +``` +```bash +curl -X GET \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <YOUR_API_KEY>" \ + https://<REGION>.cloud.appwrite.io/v1/mysql/<DATABASE_ID> +``` +{% /multicode %} + +The response includes the connection fields alongside the database configuration: + +```json +{ + "$id": "<DATABASE_ID>", + "name": "main", + "engine": "mysql", + "version": "8.4", + "status": "ready", + "hostname": "db-<hash>.<region>.appwrite.center", + "connectionPort": 3306, + "connectionUser": "admin", + "connectionPassword": "<password>", + "connectionString": "mysql://admin:<password>@db-<hash>.<region>.appwrite.center:3306/<database>" +} +``` + +The primary user is `admin` and the database name is generated per database. + +# Connect with the mysql client {% #mysql-client %} + +Pass the individual connection values to the `mysql` command-line client and enter the password when prompted: + +```bash +mysql -h db-<hash>.<region>.appwrite.center -P 3306 -u admin -p -D <database> +``` + +# Rotate the primary password {% #rotate %} + +If your password is compromised, or your security policy requires regular rotation, you can issue a new password for the primary user. The change is applied atomically in the engine, and the response carries the new connection details. Existing sessions stay alive until they disconnect, then have to authenticate with the new password. The API key needs the `databases.write` scope. + +{% multicode %} +```server-nodejs +import { Client, Mysql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +const database = await mysql.updateCredentials({ + databaseId: '<DATABASE_ID>', +}); +``` +```server-deno +import { Client, Mysql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +const database = await mysql.updateCredentials({ + databaseId: '<DATABASE_ID>', +}); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Mysql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$mysql = new Mysql($client); + +$database = $mysql->updateCredentials(databaseId: '<DATABASE_ID>'); +``` +```server-python +from appwrite.client import Client +from appwrite.services.mysql import Mysql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +mysql = Mysql(client) + +database = mysql.update_credentials(database_id='<DATABASE_ID>') +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +mysql = Mysql.new(client) + +database = mysql.update_credentials(database_id: '<DATABASE_ID>') +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Mysql mysql = new Mysql(client); + +var database = await mysql.UpdateCredentials(databaseId: "<DATABASE_ID>"); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Mysql mysql = Mysql(client); + +final database = await mysql.updateCredentials( + databaseId: '<DATABASE_ID>', +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Mysql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val mysql = Mysql(client) + +val database = mysql.updateCredentials( + databaseId = "<DATABASE_ID>", +) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let mysql = Mysql(client) + +let database = try await mysql.updateCredentials( + databaseId: "<DATABASE_ID>" +) +``` +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + mysql := appwrite.NewMysql(client) + + _, err := mysql.UpdateCredentials("<DATABASE_ID>") + if err != nil { + panic(err) + } +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::mysql::Mysql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let mysql = Mysql::new(&client); + + let database = mysql.update_credentials("<DATABASE_ID>").await?; + + Ok(()) +} +``` +```bash +curl -X PATCH \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <YOUR_API_KEY>" \ + https://<REGION>.cloud.appwrite.io/v1/mysql/<DATABASE_ID>/credentials +``` +{% /multicode %} + +# TLS {% #tls %} + +Connections on Appwrite Cloud are encrypted with TLS, terminated at the edge and forwarded to your database over the internal network. The connection string returned on the database object carries the right SSL settings for your environment, so drivers need no extra configuration. + +For IP allowlists and other network controls, see [network security](/docs/products/databases/mysql/network-security). + +# Connecting from an application {% #drivers %} + +There is nothing Appwrite-specific about the driver setup. A few example snippets: + +{% multicode %} +```server-nodejs +import mysql from 'mysql2/promise'; + +const connection = await mysql.createConnection(process.env.DATABASE_URL); + +const [rows] = await connection.query('SELECT NOW() AS now'); +console.log(rows); + +await connection.end(); +``` +```server-python +import os +import mysql.connector + +conn = mysql.connector.connect( + host=os.environ['DB_HOST'], + port=3306, + user='admin', + password=os.environ['DB_PASSWORD'], + database=os.environ['DB_NAME'], +) +cur = conn.cursor() +cur.execute('SELECT NOW()') +print(cur.fetchone()) +conn.close() +``` +```server-php +<?php + +$pdo = new PDO( + sprintf('mysql:host=%s;port=3306;dbname=%s', getenv('DB_HOST'), getenv('DB_NAME')), + 'admin', + getenv('DB_PASSWORD') +); + +$rows = $pdo->query('SELECT NOW()')->fetchAll(); +print_r($rows); +``` +```server-go +package main + +import ( + "database/sql" + "fmt" + "os" + + _ "github.com/go-sql-driver/mysql" +) + +func main() { + db, err := sql.Open("mysql", os.Getenv("MYSQL_DSN")) + if err != nil { + panic(err) + } + defer db.Close() + + var now string + if err := db.QueryRow("SELECT NOW()").Scan(&now); err != nil { + panic(err) + } + fmt.Println(now) +} +``` +```server-rust +use sqlx::mysql::MySqlPoolOptions; +use sqlx::Row; + +#[tokio::main] +async fn main() -> Result<(), sqlx::Error> { + let url = std::env::var("DATABASE_URL").expect("DATABASE_URL"); + let pool = MySqlPoolOptions::new().connect(&url).await?; + + let row = sqlx::query("SELECT NOW() AS now").fetch_one(&pool).await?; + let now: chrono::DateTime<chrono::Utc> = row.get("now"); + println!("{now}"); + + Ok(()) +} +``` +{% /multicode %} + +Set the environment variables from the connection details on the database object. Once you can run a query, you can use any tool that talks the MySQL wire protocol: MySQL Workbench, DataGrip, your ORM of choice, your migration tool of choice. Appwrite gets out of the way. diff --git a/src/routes/docs/products/databases/mysql/high-availability/+page.markdoc b/src/routes/docs/products/databases/mysql/high-availability/+page.markdoc new file mode 100644 index 00000000000..9a644f549ed --- /dev/null +++ b/src/routes/docs/products/databases/mysql/high-availability/+page.markdoc @@ -0,0 +1,631 @@ +--- +layout: article +title: High availability +description: Run up to five read replicas with asynchronous, synchronous, or quorum replication and automatic failover for your MySQL database. +--- + +A single database instance is a single point of failure. High availability (HA) adds streaming replicas next to your primary: they replicate continuously, serve read traffic through the [connection pooler](/docs/products/databases/mysql/connection-pooling), and take over automatically when the primary becomes unhealthy. + +High availability requires a specification that runs on dedicated compute; the smallest specifications run on shared capacity and do not support replicas. + +# How it works {% #how-it-works %} + +Replicas receive changes from the primary through MySQL binary log replication. Each replica is a full copy of the database on its own compute. When the primary fails, the most caught-up replica is promoted to primary and the hostname is repointed, your application keeps connecting to the same host and port. + +# Replication modes {% #sync-modes %} + +| Mode | Behavior | Trade-off | +|----------|----------------------------------------------------------------------------------|--------------------------------------------------| +| `async` | The primary commits without waiting for replicas | Fastest writes; a failover can lose the last moments of writes | +| `sync` | The primary waits for one replica to confirm each commit | No data loss on single failure; slightly higher write latency | +| `quorum` | The primary waits for a majority of replicas to confirm each commit | Strongest durability; highest write latency | + +`async` is the default. For production workloads that cannot lose acknowledged writes, use `sync` with at least two replicas. + +# Enable high availability {% #enable %} + +Set the replica count and replication mode on the database through the API: + +{% multicode %} +```server-nodejs +import { Client, Mysql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +await mysql.update({ + databaseId: '<DATABASE_ID>', + replicas: 2, + syncMode: 'sync', +}); +``` +```server-deno +import { Client, Mysql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +await mysql.update({ + databaseId: '<DATABASE_ID>', + replicas: 2, + syncMode: 'sync', +}); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Mysql; + +$client = (new Client()) + ->setEndpoint('https://cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$mysql = new Mysql($client); + +$mysql->update( + databaseId: '<DATABASE_ID>', + replicas: 2, + syncMode: 'sync', +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.mysql import Mysql + +client = Client() +client.set_endpoint('https://cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +mysql = Mysql(client) + +mysql.update( + database_id='<DATABASE_ID>', + replicas=2, + sync_mode='sync', +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +mysql = Mysql.new(client) + +mysql.update( + database_id: '<DATABASE_ID>', + replicas: 2, + sync_mode: 'sync', +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Mysql mysql = new Mysql(client); + +await mysql.Update( + databaseId: "<DATABASE_ID>", + replicas: 2, + syncMode: "sync" +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Mysql mysql = Mysql(client); + +await mysql.update( + databaseId: '<DATABASE_ID>', + replicas: 2, + syncMode: 'sync', +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Mysql + +val client = Client() + .setEndpoint("https://cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val mysql = Mysql(client) + +mysql.update( + databaseId = "<DATABASE_ID>", + replicas = 2, + syncMode = "sync", +) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let mysql = Mysql(client) + +_ = try await mysql.update( + databaseId: "<DATABASE_ID>", + replicas: 2, + syncMode: "sync" +) +``` +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" + "github.com/appwrite/sdk-for-go/mysql" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewMysql(client) + + _, err := service.Update( + "<DATABASE_ID>", + mysql.WithUpdateReplicas(2), + mysql.WithUpdateSyncMode("sync"), + ) + if err != nil { + panic(err) + } +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::mysql::Mysql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let mysql = Mysql::new(&client); + + mysql.update("<DATABASE_ID>", None, None, None, Some(2), Some("sync"), None, None, None, None, None, None, None, None, None, None, None, None, None, None, None).await?; + + Ok(()) +} +``` +```bash +curl -X PATCH \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <YOUR_API_KEY>" \ + -H "Content-Type: application/json" \ + -d '{ + "replicas": 2, + "syncMode": "sync" + }' \ + https://cloud.appwrite.io/v1/mysql/<DATABASE_ID> +``` +{% /multicode %} + +Adding replicas provisions them online; the primary keeps serving traffic while each replica seeds from a snapshot and catches up. Setting `replicas` back to `0` disables HA. + +# Check replication status {% #status %} + +You can check each replica's role, health, and replication lag: + +{% multicode %} +```server-nodejs +import { Client, Mysql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +const replicas = await mysql.getReplicas({ + databaseId: '<DATABASE_ID>', +}); +``` +```server-deno +import { Client, Mysql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +const replicas = await mysql.getReplicas({ + databaseId: '<DATABASE_ID>', +}); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Mysql; + +$client = (new Client()) + ->setEndpoint('https://cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$mysql = new Mysql($client); + +$replicas = $mysql->getReplicas( + databaseId: '<DATABASE_ID>', +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.mysql import Mysql + +client = Client() +client.set_endpoint('https://cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +mysql = Mysql(client) + +replicas = mysql.get_replicas( + database_id='<DATABASE_ID>', +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +mysql = Mysql.new(client) + +replicas = mysql.get_replicas( + database_id: '<DATABASE_ID>', +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Mysql mysql = new Mysql(client); + +var replicas = await mysql.GetReplicas( + databaseId: "<DATABASE_ID>" +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Mysql mysql = Mysql(client); + +final replicas = await mysql.getReplicas( + databaseId: '<DATABASE_ID>', +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Mysql + +val client = Client() + .setEndpoint("https://cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val mysql = Mysql(client) + +val replicas = mysql.getReplicas( + databaseId = "<DATABASE_ID>", +) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let mysql = Mysql(client) + +let replicas = try await mysql.getReplicas( + databaseId: "<DATABASE_ID>" +) +``` +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewMysql(client) + + result, err := service.GetReplicas("<DATABASE_ID>") + if err != nil { + panic(err) + } + _ = result +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::mysql::Mysql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let mysql = Mysql::new(&client); + + let replicas = mysql.get_replicas("<DATABASE_ID>").await?; + + Ok(()) +} +``` +```bash +curl -X GET \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <YOUR_API_KEY>" \ + https://cloud.appwrite.io/v1/mysql/<DATABASE_ID>/replicas +``` +{% /multicode %} + +# Automatic failover {% #automatic-failover %} + +Appwrite continuously health-checks the primary. When it becomes unresponsive, the platform promotes the replica with the least replication lag, repoints the database hostname, and marks the old primary for replacement. Your application reconnects to the same hostname; a well-configured driver pool retries and recovers without intervention. + +With `async` replication, writes that had not yet reached the promoted replica are lost in a failover. Use `sync` or `quorum` if that is unacceptable. + +# Manual failover {% #manual-failover %} + +Trigger a failover yourself, for example to test your application's recovery behavior. Optionally pass `targetReplicaId` to promote a specific replica. + +{% multicode %} +```server-nodejs +import { Client, Mysql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +await mysql.createFailover({ + databaseId: '<DATABASE_ID>', +}); +``` +```server-deno +import { Client, Mysql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +await mysql.createFailover({ + databaseId: '<DATABASE_ID>', +}); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Mysql; + +$client = (new Client()) + ->setEndpoint('https://cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$mysql = new Mysql($client); + +$mysql->createFailover( + databaseId: '<DATABASE_ID>', +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.mysql import Mysql + +client = Client() +client.set_endpoint('https://cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +mysql = Mysql(client) + +mysql.create_failover( + database_id='<DATABASE_ID>', +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +mysql = Mysql.new(client) + +mysql.create_failover( + database_id: '<DATABASE_ID>', +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Mysql mysql = new Mysql(client); + +await mysql.CreateFailover( + databaseId: "<DATABASE_ID>" +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Mysql mysql = Mysql(client); + +await mysql.createFailover( + databaseId: '<DATABASE_ID>', +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Mysql + +val client = Client() + .setEndpoint("https://cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val mysql = Mysql(client) + +mysql.createFailover( + databaseId = "<DATABASE_ID>", +) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let mysql = Mysql(client) + +_ = try await mysql.createFailover( + databaseId: "<DATABASE_ID>" +) +``` +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewMysql(client) + + _, err := service.CreateFailover("<DATABASE_ID>") + if err != nil { + panic(err) + } +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::mysql::Mysql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let mysql = Mysql::new(&client); + + mysql.create_failover("<DATABASE_ID>", None).await?; + + Ok(()) +} +``` +```bash +curl -X POST \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <YOUR_API_KEY>" \ + https://cloud.appwrite.io/v1/mysql/<DATABASE_ID>/failovers +``` +{% /multicode %} + +# Reading from replicas {% #reads %} + +Replicas serve read traffic when [read/write splitting](/docs/products/databases/mysql/connection-pooling#read-write-splitting) is enabled on the connection pooler. With `async` replication, a read that immediately follows a write can return stale data. Route reads that must see the latest write to the primary, or use `sync` replication. + +# Limits and billing {% #limits %} + +- Up to 5 replicas per database; the maximum depends on your plan. +- Each replica runs on the same specification as the primary and is billed as an add-on. See [pricing](/pricing). +- Replicas live in the same region as the primary. diff --git a/src/routes/docs/products/databases/mysql/integrations/auth-js/+page.markdoc b/src/routes/docs/products/databases/mysql/integrations/auth-js/+page.markdoc new file mode 100644 index 00000000000..e22e5c24910 --- /dev/null +++ b/src/routes/docs/products/databases/mysql/integrations/auth-js/+page.markdoc @@ -0,0 +1,222 @@ +--- +layout: article +title: Auth.js +description: Use an Appwrite native MySQL database as the backing store for Auth.js (NextAuth.js). Persist users, accounts, and sessions through the Prisma adapter. +--- + +[Auth.js](https://authjs.dev/) (formerly NextAuth.js) persists users, accounts, sessions, and verification tokens through a database adapter. When you configure an adapter, those records live in your database, which makes database sessions, account linking, and email sign-in possible. An Appwrite [native MySQL database](/docs/products/databases/mysql) is a standard MySQL engine, so Auth.js works through the same ORM adapters you use with other MySQL databases. + +{% info title="Before you start" %} +You'll need a native MySQL database in a `ready` state and its credentials. See [native MySQL databases](/docs/products/databases/mysql) to create one with the create-database wizard, then use [Connections](/docs/products/databases/mysql/connections#credentials) to read the hostname, password, database name, and connection string with `mysql.get()`. +{% /info %} + +# Choose an adapter {% #adapter %} + +Auth.js talks to your database through an adapter. For a native MySQL database, use the adapter that matches your ORM: + +- **Prisma** through [`@auth/prisma-adapter`](https://authjs.dev/getting-started/adapters/prisma). This page shows the Prisma setup with Prisma's MySQL provider and `@prisma/adapter-mariadb`. +- **Drizzle** through [`@auth/drizzle-adapter`](https://authjs.dev/getting-started/adapters/drizzle). Use Drizzle's MySQL schema and a `mysql2` database instance, then pass `DrizzleAdapter(db)` to Auth.js. See the [Drizzle guide](/docs/products/databases/mysql/integrations/drizzle) for the MySQL driver and migration setup. + +# Install packages {% #install %} + +Install Auth.js, the Prisma adapter, Prisma Client, Prisma's MySQL driver adapter, and the MariaDB driver used by the adapter: + +```bash +npm install next-auth@beta @auth/prisma-adapter @prisma/client @prisma/adapter-mariadb mariadb dotenv +npm install -D prisma typescript tsx @types/node +``` + +# Set the connection strings {% #connection-strings %} + +Store the Appwrite connection string in environment variables and do not commit it. Prisma uses `sslaccept=strict` for TLS with certificate verification on MySQL connections: + +```env +DATABASE_URL="mysql://admin:<password>@db-<hash>.<region>.appwrite.center:3306/<database>?sslaccept=strict" +DIRECT_URL="mysql://admin:<password>@db-<hash>.<region>.appwrite.center:3306/<database>?sslaccept=strict" + +# Runtime pooler, if your database specification includes connection pooling +# DATABASE_URL="mysql://admin:<password>@db-<hash>.<region>.appwrite.center:6033/<database>?sslaccept=strict" +``` + +`DATABASE_URL` is the runtime connection used by Prisma Client. `DIRECT_URL` is the direct MySQL connection used by Prisma CLI commands for migrations and introspection. Keep migrations on port `3306`; if you use the [connection pooler](/docs/products/databases/mysql/connection-pooling) for runtime traffic, only move `DATABASE_URL` to port `6033`. + +# Create the adapter schema {% #schema %} + +Auth.js expects four Prisma models: `User`, `Account`, `Session`, and `VerificationToken`. Add them to `prisma/schema.prisma` with the MySQL provider. The table names below use an `auth_js_` prefix so they stay separate from your application tables. + +```prisma +generator client { + provider = "prisma-client" + output = "../generated/prisma" +} + +datasource db { + provider = "mysql" +} + +model User { + id String @id @default(cuid()) + name String? + email String? @unique + emailVerified DateTime? + image String? + accounts Account[] + sessions Session[] + + @@map("auth_js_users") +} + +model Account { + id String @id @default(cuid()) + userId String + type String + provider String + providerAccountId String + refresh_token String? @db.Text + access_token String? @db.Text + expires_at Int? + token_type String? + scope String? + id_token String? @db.Text + session_state String? + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + + @@unique([provider, providerAccountId]) + @@map("auth_js_accounts") +} + +model Session { + id String @id @default(cuid()) + sessionToken String @unique + userId String + expires DateTime + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + + @@map("auth_js_sessions") +} + +model VerificationToken { + identifier String + token String + expires DateTime + + @@unique([identifier, token]) + @@map("auth_js_verification_tokens") +} +``` + +Configure Prisma CLI commands in `prisma.config.ts`. The CLI uses `DIRECT_URL` because migrations need a direct MySQL session. + +```ts +import 'dotenv/config'; +import { defineConfig, env } from 'prisma/config'; + +export default defineConfig({ + schema: 'prisma/schema.prisma', + migrations: { + path: 'prisma/migrations' + }, + datasource: { + url: env('DIRECT_URL') + } +}); +``` + +# Run the migration {% #migrate %} + +Create a migration file from the Auth.js schema: + +```bash +mkdir -p prisma/migrations/20260708160000_authjs_init +npx prisma migrate diff --from-empty --to-schema prisma/schema.prisma --script --output prisma/migrations/20260708160000_authjs_init/migration.sql +``` + +Apply committed migrations through the direct MySQL connection: + +```bash +npx prisma migrate deploy +``` + +Generate Prisma Client after you install dependencies or change `prisma/schema.prisma`: + +```bash +npx prisma generate +``` + +Prisma's `migrate dev` command uses a shadow database to detect schema drift. Use it against a local MySQL database, a separate Appwrite database, or an Appwrite branch, then apply committed migrations to this database with `migrate deploy`. + +# Wire the adapter into Auth.js {% #config %} + +Create one Prisma Client with Prisma's MySQL driver adapter: + +```ts +import 'dotenv/config'; +import { PrismaMariaDb } from '@prisma/adapter-mariadb'; +import { PrismaClient } from '../generated/prisma/client'; + +const connectionString = process.env.DATABASE_URL; +if (!connectionString) throw new Error('DATABASE_URL is required'); + +const adapter = new PrismaMariaDb(connectionString); + +export const prisma = new PrismaClient({ adapter }); +``` + +Pass the Prisma Client to your Auth.js config through the `adapter` key: + +```ts +import NextAuth from 'next-auth'; +import { PrismaAdapter } from '@auth/prisma-adapter'; +import { prisma } from './prisma'; + +export const { handlers, auth, signIn, signOut } = NextAuth({ + adapter: PrismaAdapter(prisma), + session: { strategy: 'database' }, + providers: [ + // your providers, e.g. GitHub, Google, Resend + ] +}); +``` + +# Database vs JWT sessions {% #sessions %} + +Auth.js has two session strategies: + +- **`database`**: a session row is written to the `Session` model and only an opaque session ID is stored in an `HttpOnly` cookie. Each request looks the session up in the native MySQL database, and sessions can be revoked server-side. +- **`jwt`**: session state lives in a signed cookie, and the database is not read on the session path. + +When you set `strategy: "database"`, keep the `Session` model in your Prisma schema. With `strategy: "jwt"`, the adapter still persists users and linked accounts, so account linking and user management continue to use the database. + +# Pool connections from serverless {% #pooling %} + +On serverless and edge platforms, each running instance opens its own database connections. On specifications that include the [connection pooler](/docs/products/databases/mysql/connection-pooling), route runtime traffic through port `6033` by setting `DATABASE_URL` to the pooler URL while keeping `DIRECT_URL` on port `3306`. + +The pooler defaults to transaction mode, which gives the highest connection multiplexing. Transaction mode does not keep a backend connection across statements, so session-level features such as user variables, temporary tables, and session-scoped prepared statements need session mode or a direct connection. + +# Use a branch for previews {% #branches %} + +[Branches](/docs/products/databases/mysql/branches) are isolated copies of a database with their own hostname and connection string. They are useful for pull-request previews and integration-test jobs that sign users in and out against throwaway data: + +1. Create a branch from the API and read its `connectionString`. +2. Export it as `DIRECT_URL`, and use the pooled variant as `DATABASE_URL` if the branch has the pooler enabled. +3. Run `npx prisma migrate deploy` and your auth flow against the branch. +4. Delete the branch when the job finishes. + +Because a branch starts from a storage snapshot, the Auth.js tables and data match the source database at branch time, so preview sign-ins behave like production without touching it. + +# Related {% #related %} + +{% cards %} +{% cards_item href="/docs/products/databases/mysql/integrations/prisma" title="Prisma" %} +Datasource, driver adapter, and migrations for Prisma. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/integrations/drizzle" title="Drizzle" %} +Driver connection, schema definitions, and drizzle-kit migrations for MySQL. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/connection-pooling" title="Connection pooler" %} +Pool modes, ports, and serverless connection handling. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/integrations/better-auth" title="Better Auth" %} +The same pattern for Better Auth on a native MySQL database. +{% /cards_item %} +{% /cards %} diff --git a/src/routes/docs/products/databases/mysql/integrations/better-auth/+page.markdoc b/src/routes/docs/products/databases/mysql/integrations/better-auth/+page.markdoc new file mode 100644 index 00000000000..cc9ffe323ad --- /dev/null +++ b/src/routes/docs/products/databases/mysql/integrations/better-auth/+page.markdoc @@ -0,0 +1,139 @@ +--- +layout: article +title: Better Auth +description: Use an Appwrite native MySQL database as the database for Better Auth. Configure mysql2, run schema generation and migrations over a direct connection, and store users and sessions in MySQL. +--- + +[Better Auth](https://www.better-auth.com/) is a framework-agnostic authentication library for TypeScript that stores users, sessions, accounts, and verification records in your database. An Appwrite [native MySQL database](/docs/products/databases/mysql) gives Better Auth a standard MySQL engine, so you can use `mysql2`, run the Better Auth CLI, and keep auth data in your Appwrite project. + +{% info title="Before you start" %} +You'll need a native MySQL database in a `ready` state and its credentials. See [native MySQL databases](/docs/products/databases/mysql) to create one and [Connections](/docs/products/databases/mysql/connections) to retrieve the connection string. The primary user is `admin`, and the database name is generated per database. +{% /info %} + +# Set the connection strings {% #connection-strings %} + +Better Auth uses one database URL at runtime and another for schema work. Use the pooler URL for application traffic when your specification includes the pooler, and use the direct engine URL for schema generation and migrations. + +```env +# Runtime: pooled, transaction mode +DATABASE_URL="mysql://admin:<password>@db-<hash>.<region>.appwrite.center:6033/<database>" + +# Schema generation and migrations: direct connection to the engine +DIRECT_URL="mysql://admin:<password>@db-<hash>.<region>.appwrite.center:3306/<database>" + +MYSQL_SSL="true" +BETTER_AUTH_URL="https://example.com" +BETTER_AUTH_SECRET="replace-with-a-long-random-secret" +``` + +The MySQL pooler runs on port `6033`, and the engine runs on port `3306`. The smallest shared-capacity specifications do not include the pooler, so use the direct URL for runtime traffic on those specifications. Connections on Appwrite Cloud are encrypted with TLS. The `MYSQL_SSL` variable below lets local development use an unencrypted port-forward while Cloud uses TLS verification. See [Connections](/docs/products/databases/mysql/connections) for connection fields and [Connection pooling](/docs/products/databases/mysql/connection-pooling#modes) for pool modes. + +# Install Better Auth and mysql2 {% #install %} + +Install Better Auth with the MySQL driver: + +```bash +npm install better-auth mysql2 +``` + +# Configure Better Auth {% #configure %} + +Pass a `mysql2/promise` pool to Better Auth. Better Auth drives that pool through its built-in Kysely adapter, so the Better Auth CLI can generate and apply the schema for you. + +The example below gives Better Auth tables a `better_auth_` prefix. Keep those model names if you want the auth tables grouped together, or choose names that match your schema conventions. + +```ts +import { betterAuth } from 'better-auth'; +import { createPool } from 'mysql2/promise'; + +if (!process.env.DATABASE_URL) { + throw new Error('DATABASE_URL is required'); +} + +const ssl = + process.env.MYSQL_SSL === 'true' + ? { rejectUnauthorized: true } + : undefined; + +export const auth = betterAuth({ + baseURL: process.env.BETTER_AUTH_URL, + secret: process.env.BETTER_AUTH_SECRET, + database: createPool({ + uri: process.env.DATABASE_URL, + timezone: 'Z', + ssl + }), + emailAndPassword: { enabled: true }, + user: { modelName: 'better_auth_user' }, + session: { modelName: 'better_auth_session' }, + account: { modelName: 'better_auth_account' }, + verification: { modelName: 'better_auth_verification' } +}); +``` + +`timezone: 'Z'` keeps timestamp values consistent between your application and MySQL. Leave mysql2's default `FOUND_ROWS` behavior enabled, because Better Auth relies on matched-row counts for some updates. + +# Generate and migrate the schema {% #migrate %} + +The [Better Auth CLI](https://www.better-auth.com/docs/concepts/cli) reads your `auth` config and creates the tables it needs. Run schema commands with the direct URL so DDL runs over a session connection: + +```bash +DATABASE_URL="$DIRECT_URL" npx auth@latest generate --config ./auth.ts --yes +``` + +Then apply the schema: + +```bash +DATABASE_URL="$DIRECT_URL" npx auth@latest migrate --config ./auth.ts --yes +``` + +`migrate` is available for Better Auth's built-in Kysely adapter. If you use the Better Auth Prisma or Drizzle adapter, run `generate` to produce that ORM's schema, then apply it with the ORM migration tool over `DIRECT_URL`. See the [Prisma](/docs/products/databases/mysql/integrations/prisma) and [Drizzle](/docs/products/databases/mysql/integrations/drizzle) guides for their MySQL configuration. + +# Create a user {% #example %} + +After the schema exists, mount Better Auth's handler in your framework and call the API methods from your server code: + +```ts +import { auth } from './auth'; + +const result = await auth.api.signUpEmail({ + body: { + email: 'ada@example.com', + password: 'a-strong-password', + name: 'Ada Lovelace' + } +}); + +console.log(result.user.id); +``` + +On a long-running server, create the `auth` instance once at module scope and reuse it. On serverless, keep a single instance per module scope so warm invocations reuse the mysql2 pool. + +# Pooling and session state {% #pooling %} + +Auth workloads, including sign-up, login, and session lookups, are short database transactions. Pointing runtime traffic at port `6033` lets many application instances share a smaller backend connection pool when the pooler is available. + +The pooler's transaction mode does not keep a backend connection across statements. Better Auth's built-in MySQL path works through Kysely and mysql2 text queries, which fit transaction pooling. If your surrounding application code uses session-bound features such as server-side prepared statements, user variables, or temporary tables, use the direct port or switch the pooler to session mode. See [pooler modes](/docs/products/databases/mysql/connection-pooling#modes) for the trade-offs. + +# Related {% #related %} + +{% cards %} +{% cards_item href="/docs/products/databases/mysql/connections" title="Connections" %} +Retrieve credentials and rotate the primary password. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/connection-pooling" title="Connection pooling" %} +Pool modes, ports, and read/write splitting for serverless workloads. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/integrations/prisma" title="Prisma" %} +Configure Prisma with pooled and direct MySQL URLs. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/integrations/drizzle" title="Drizzle" %} +Configure Drizzle ORM with mysql2 and Drizzle Kit migrations. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/branches" title="Branches" %} +Ephemeral database copies for preview environments and CI. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/integrations/auth-js" title="Auth.js" %} +Use a native MySQL database as the Auth.js database. +{% /cards_item %} +{% /cards %} diff --git a/src/routes/docs/products/databases/mysql/integrations/dbt/+page.markdoc b/src/routes/docs/products/databases/mysql/integrations/dbt/+page.markdoc new file mode 100644 index 00000000000..ec03efb9275 --- /dev/null +++ b/src/routes/docs/products/databases/mysql/integrations/dbt/+page.markdoc @@ -0,0 +1,113 @@ +--- +layout: article +title: dbt +description: Run dbt Core transformations against an Appwrite native MySQL database with the community dbt-mysql adapter. +--- + +Use dbt Core with an Appwrite native MySQL database through the community [`dbt-mysql`](https://docs.getdbt.com/docs/local/connect-data-platform/mysql-setup) adapter. Appwrite exposes standard MySQL on port `3306`, so dbt connects with the same host, username, password, and database name you use with other MySQL clients. + +dbt compiles your models into `CREATE TABLE` and `CREATE VIEW` statements, then runs them in dependency order to build transformed tables and views inside the MySQL database you configure. + +{% info title="Adapter support" %} +dbt Labs lists MySQL as a community adapter. The published [`dbt-mysql`](https://pypi.org/project/dbt-mysql/) package is experimental and is not dbt-supported, so pin and test the adapter version you deploy. +{% /info %} + +{% info title="Before you start" %} +You'll need a native MySQL database in a `ready` state and its credentials. See [MySQL](/docs/products/databases/mysql) to create one and [Connections](/docs/products/databases/mysql/connections) to retrieve them. The primary user is `admin`, the database name is generated for each database, and the engine listens on port `3306`. +{% /info %} + +# Install the adapter {% #install %} + +Install dbt Core and the MySQL adapter in the Python environment where you run dbt: + +```bash +python -m pip install dbt-mysql +``` + +# Choose where dbt builds {% #build-location %} + +In MySQL, dbt's `schema` setting is the MySQL database name. Set `schema` to the generated database name from your Appwrite connection details. + +Use a naming convention such as a `dbt_` prefix for dbt models and seeds, for example `dbt_orders` and `dbt_customer_revenue`, to keep transformed tables separate from application tables in the same database. For stricter isolation, use another native MySQL database or validate changes against a branch. + +# Configure profiles.yml {% #profiles %} + +dbt reads connection details from `~/.dbt/profiles.yml` or the directory in `DBT_PROFILES_DIR`. Configure a `mysql` target against the database host on port `3306`: + +```yaml +analytics: + target: dev + outputs: + dev: + type: mysql + server: db-<hash>.<region>.appwrite.center + port: 3306 + username: admin + password: "{{ env_var('APPWRITE_DB_PASSWORD') }}" + schema: <database> + threads: 4 + charset: utf8mb4 + collation: utf8mb4_0900_ai_ci +``` + +The `dbt-mysql` adapter uses `server`, `username`, `password`, and `schema`. Read the password from an environment variable with `env_var` rather than committing it. The `schema` value is the generated MySQL database name from your Appwrite connection string. + +# Test the connection {% #debug %} + +`dbt debug` validates your project files and opens a connection to confirm the credentials and host are correct: + +```bash +dbt debug +``` + +A successful run reports `Connection test: OK connection ok`. If it fails, recheck the host, port, password, and database name. + +# Run transformations {% #run %} + +Build your models into the configured MySQL database: + +```bash +dbt run +``` + +`dbt run` executes models only, materializing each as a table or view. Use `dbt build` to run models, tests, seeds, and snapshots together in DAG order: + +```bash +dbt build +``` + +# Choose the right connection {% #connection %} + +dbt opens one database connection per thread and runs DDL during model builds. Point dbt at a connection that preserves the session for each thread: + +- **Direct engine port (`3306`)** is the recommended target. Each thread gets a backend session with the DDL privileges dbt needs. This is what the `profiles.yml` above uses. +- **Session-mode pooler** can work when the pooler is available for your database specification. Connect on the pooler port (`6033`) and use `session` mode. + +Avoid the transaction-mode pooler for dbt. Transaction mode returns the backend connection to the pool after each transaction, which can break workflows that rely on session state. See the [connection pooling](/docs/products/databases/mysql/connection-pooling#modes) page for the mode trade-offs. + +# Size threads to your connection budget {% #threads %} + +The `threads` setting controls how many models dbt builds in parallel, and dbt opens one connection per thread. A `threads: 8` run can hold up to eight backend connections at once. dbt also respects model dependencies, so it never runs more models concurrently than your DAG allows. + +Pick a `threads` value that fits the connection budget for your database specification, and leave headroom for application traffic sharing the same database. Start at `4` and raise it only while connections stay within budget. + +# Related {% #related %} + +{% cards %} +{% cards_item href="/docs/products/databases/mysql/connections" title="Connections" %} +Retrieve credentials and rotate the primary password. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/connection-pooling" title="Connection pooler" %} +Pool modes and ports. Use session mode for dbt. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/branches" title="Branches" %} +Ephemeral database copies for CI and preview environments. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/network-security" title="Network" %} +TLS behavior, certificate verification, and IP allowlists. +{% /cards_item %} +{% /cards %} + +{% arrow_link href="https://docs.getdbt.com/docs/local/connect-data-platform/mysql-setup" %} +dbt MySQL adapter reference +{% /arrow_link %} diff --git a/src/routes/docs/products/databases/mysql/integrations/django/+page.markdoc b/src/routes/docs/products/databases/mysql/integrations/django/+page.markdoc new file mode 100644 index 00000000000..419751ce299 --- /dev/null +++ b/src/routes/docs/products/databases/mysql/integrations/django/+page.markdoc @@ -0,0 +1,151 @@ +--- +layout: article +title: Django +description: Use Django's ORM with an Appwrite native MySQL database. Configure the DATABASES setting, run migrations against the direct MySQL port, and choose the right pooler mode for Django connections. +--- + +A native MySQL database is a standard MySQL engine, so Django's ORM works against it with no Appwrite-specific configuration. Point the `DATABASES` setting at the credentials from the [Connections](/docs/products/databases/mysql/connections) page, then use migrations, models, and the rest of Django as you would against any MySQL server. + +{% info title="Before you start" %} +You'll need a native MySQL database in a `ready` state and its credentials. See [native MySQL databases](/docs/products/databases/mysql) to create one with the create-database wizard, then use [`mysql.get()`](/docs/products/databases/mysql/connections#credentials) to read the hostname, port, username, password, and generated database name. The primary username is `admin`. +{% /info %} + +# Install a driver {% #driver %} + +Django talks to MySQL through a DB API driver. Django's current recommended driver is [mysqlclient](https://pypi.org/project/mysqlclient/): + +```bash +pip install mysqlclient +``` + +`mysqlclient` builds against MySQL client libraries. If installation fails, install the MySQL development headers and `pkg-config` for your operating system, then run the same command again. + +Django's MySQL backend uses the `ENGINE` value `django.db.backends.mysql`. + +# Configure `DATABASES` {% #databases %} + +In `settings.py`, point the `default` connection at your native MySQL database. Appwrite Cloud requires TLS on the public hostname, and the certificate is signed by a public certificate authority. Read every value from the environment so credentials stay out of source control: + +```python +import os + +DATABASES = { + "default": { + "ENGINE": "django.db.backends.mysql", + "NAME": os.environ["DB_NAME"], + "USER": os.environ["DB_USER"], + "PASSWORD": os.environ["DB_PASSWORD"], + "HOST": os.environ["DB_HOST"], + "PORT": os.environ["DB_PORT"], + "OPTIONS": { + "charset": "utf8mb4", + "ssl_mode": os.environ.get("DB_SSL_MODE", "REQUIRED"), + }, + } +} +``` + +The MySQL backend passes `OPTIONS` to `mysqlclient`. `charset` keeps client encoding aligned with Django's UTF-8 expectations, and `ssl_mode` controls TLS for the MySQL connection. Use `REQUIRED` for encrypted Cloud connections. For full certificate and hostname verification, set `DB_SSL_MODE=VERIFY_IDENTITY`. See [Network security](/docs/products/databases/mysql/network-security) for TLS and IP allowlist guidance. + +Populate the environment with values from `mysql.get()` in the [API credentials flow](/docs/products/databases/mysql/connections#credentials): + +```env +DB_NAME=<database> +DB_USER=admin +DB_PASSWORD=<password> +DB_HOST=db-<hash>.<region>.appwrite.center +DB_PORT=3306 +DB_SSL_MODE=REQUIRED +``` + +Port `3306` is the direct MySQL port. Keep migrations on this port, and see [pooling](#pooling) below for when to add the pooler. + +# Run migrations {% #migrate %} + +Generate migrations from your models, then apply them against the direct MySQL port: + +```bash +python manage.py makemigrations +python manage.py migrate +``` + +`migrate` needs a session connection with DDL privileges. The primary `admin` user owns the database and can run schema changes. Always run `migrate` on the direct MySQL port, not through the transaction-mode pooler. + +# Define a model {% #model %} + +Models map to tables in your native MySQL database. Define one in an app's `models.py`: + +```python +from django.db import models + +class Article(models.Model): + title = models.CharField(max_length=200) + body = models.TextField() + created_at = models.DateTimeField(auto_now_add=True) + + class Meta: + db_table = "django_articles" + ordering = ["-created_at"] +``` + +Run `makemigrations` and `migrate` again to create the table, then query it through the ORM: + +```python +from blog.models import Article + +Article.objects.create(title="Hello", body="First post") + +recent = Article.objects.order_by("-created_at")[:10] +``` + +# Persistent connections and pooling {% #pooling %} + +By default Django opens a new connection per request (`CONN_MAX_AGE = 0`). On a long-running WSGI server (Gunicorn, uWSGI), you can reuse connections by raising it. Each worker thread keeps its own connection, so the database must allow at least as many connections as you run worker threads: + +```python +DATABASES["default"]["CONN_MAX_AGE"] = 60 +DATABASES["default"]["CONN_HEALTH_CHECKS"] = True +``` + +`CONN_HEALTH_CHECKS` revalidates a reused connection once per request, reducing errors after an engine restart. Do not enable persistent connections under the development server, because it spawns a thread per request and gains nothing. Keep persistent connections disabled under ASGI. + +{% info title="Persistent connections need a session" %} +A worker holding a connection across requests behaves like a long-lived session. Connect it to the direct MySQL port or the **session-mode** pooler. The default **transaction-mode** pooler can hand statements to different backend connections, which makes it a better fit for short-lived runtimes that open and close a connection per request or invocation. +{% /info %} + +If you front the database with the transaction-mode [connection pooler](/docs/products/databases/mysql/connection-pooling), point `HOST` and `PORT` at the MySQL pooler on port `6033` and keep `CONN_MAX_AGE = 0`: + +```env +DB_HOST=db-<hash>.<region>.appwrite.center +DB_PORT=6033 +``` + +Transaction mode does not preserve session state between statements. Use the direct port or **session mode** for migrations, temporary tables, user variables, named locks, and other session-scoped behavior. See the [pooler](/docs/products/databases/mysql/connection-pooling#modes) page for the trade-offs. + +# Use a branch for previews and CI {% #branches %} + +[Branches](/docs/products/databases/mysql/branches) are instant, isolated copies of a database with their own hostname and connection details. They're ideal for running migrations against throwaway data in a pull-request preview or an integration-test job: + +1. Create a branch from the API and read its connection details. +2. Export them as the `DB_*` environment variables your settings read. +3. Run `python manage.py migrate` and your test suite against the branch. +4. Delete the branch when the job finishes. + +Because a branch starts from a storage snapshot, its schema and data match the source database at branch time, so migrations run against realistic data without touching production. + +# Related {% #related %} + +{% cards %} +{% cards_item href="/docs/products/databases/mysql/connections" title="Connections" %} +Retrieve credentials, rotate the password, and connect with common clients. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/connection-pooling" title="Connection pooler" %} +Pool modes, ports, and read/write splitting for serverless workloads. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/branches" title="Branches" %} +Ephemeral database copies for preview environments and CI. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/network-security" title="Network security" %} +TLS, certificate verification, mTLS, and IP allowlists. +{% /cards_item %} +{% /cards %} diff --git a/src/routes/docs/products/databases/mysql/integrations/drivers/+page.markdoc b/src/routes/docs/products/databases/mysql/integrations/drivers/+page.markdoc new file mode 100644 index 00000000000..5312292c136 --- /dev/null +++ b/src/routes/docs/products/databases/mysql/integrations/drivers/+page.markdoc @@ -0,0 +1,225 @@ +--- +layout: article +title: Node.js drivers +description: Connect to an Appwrite native MySQL database from Node.js with mysql2 or MariaDB Connector/Node.js. Configure pools, TLS verification, serverless connection management, and troubleshooting. +--- + +A native MySQL database works with standard Node.js drivers that speak the MySQL wire protocol. The [Connections](/docs/products/databases/mysql/connections#drivers) page shows the smallest query. This guide covers driver pools, TLS verification, serverless connection management, and common connection errors. + +{% info title="Before you start" %} +You'll need a native MySQL database in a `ready` state and the connection values returned by the database object: host, port, username, password, and database name. Store the password in an environment variable and keep it out of source control. +{% /info %} + +# Raw driver, ORM, or SQL API? {% #choosing %} + +There are three common ways to query a native MySQL database from Node.js. Pick by workload: + +| Approach | Use it when | +|------------------------------|----------------------------------------------------------------------------------------------| +| **Raw driver** (this page) | You want a connection pool you control, hot-path queries, or a thin data layer with little overhead. | +| **ORM** ([Prisma](/docs/products/databases/mysql/integrations/prisma), [Drizzle](/docs/products/databases/mysql/integrations/drizzle)) | You want migrations, a typed schema, and query building. The ORM still uses a MySQL driver underneath. | +| **[SQL API](/docs/products/databases/mysql/quick-start#first-queries)** | You're on a runtime that cannot open TCP sockets, or you're scripting a query over HTTPS. | + +The rest of this page is for long-running or serverless Node.js servers that can open TCP connections. + +# mysql2 promise API {% #mysql2-promise %} + +Install mysql2 with `npm install mysql2`. For a long-running server, create one promise pool at module scope and reuse it for every request. The pool opens connections lazily up to `connectionLimit`. + +```js +import mysql from 'mysql2/promise'; +import process from 'node:process'; + +const pool = mysql.createPool({ + host: 'db-<hash>.<region>.appwrite.center', + port: 3306, + user: 'admin', + password: process.env.DB_PASSWORD, + database: '<database>', + ssl: { rejectUnauthorized: true }, + waitForConnections: true, + connectionLimit: 10, + idleTimeout: 30000, + enableKeepAlive: true, +}); + +await pool.query(` + CREATE TABLE IF NOT EXISTS drivers_events ( + id INT AUTO_INCREMENT PRIMARY KEY, + email VARCHAR(255) NOT NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + ) +`); + +const [result] = await pool.execute( + 'INSERT INTO drivers_events (email) VALUES (?)', + ['ada@example.com'] +); + +const [rows] = await pool.execute( + 'SELECT id, email FROM drivers_events WHERE id = ?', + [result.insertId] +); + +console.log(rows[0]); + +await pool.end(); +``` + +Use `execute` for parameterized statements on the direct MySQL port. mysql2 prepares these statements on the server and caches them per connection, which is a good fit for a stable application pool. + +# mysql2 callback API {% #mysql2-callback %} + +Use the callback API when your application already follows callback patterns. Keep the pool shared, and close it only during process shutdown. + +```js +import mysql from 'mysql2'; +import process from 'node:process'; + +const pool = mysql.createPool({ + host: 'db-<hash>.<region>.appwrite.center', + port: 3306, + user: 'admin', + password: process.env.DB_PASSWORD, + database: '<database>', + ssl: { rejectUnauthorized: true }, + waitForConnections: true, + connectionLimit: 10, + idleTimeout: 30000, + enableKeepAlive: true, +}); + +pool.query(` + CREATE TABLE IF NOT EXISTS drivers_events_callback ( + id INT AUTO_INCREMENT PRIMARY KEY, + email VARCHAR(255) NOT NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + ) +`, (createErr) => { + if (createErr) throw createErr; + + pool.execute( + 'INSERT INTO drivers_events_callback (email) VALUES (?)', + ['grace@example.com'], + (insertErr, result) => { + if (insertErr) throw insertErr; + + pool.execute( + 'SELECT id, email FROM drivers_events_callback WHERE id = ?', + [result.insertId], + (selectErr, rows) => { + if (selectErr) throw selectErr; + console.log(rows[0]); + pool.end(); + } + ); + } + ); +}); +``` + +# MariaDB Connector/Node.js {% #mariadb %} + +MariaDB Connector/Node.js is a maintained JavaScript driver for MariaDB and MySQL databases. Install it with `npm install mariadb`. Its default API is promise-based and it exposes a pool with `connectionLimit`. + +```js +import mariadb from 'mariadb'; +import process from 'node:process'; + +const pool = mariadb.createPool({ + host: 'db-<hash>.<region>.appwrite.center', + port: 3306, + user: 'admin', + password: process.env.DB_PASSWORD, + database: '<database>', + ssl: true, + connectionLimit: 10, + connectTimeout: 5000, +}); + +let connection; + +try { + connection = await pool.getConnection(); + + await connection.query(` + CREATE TABLE IF NOT EXISTS drivers_events_mariadb ( + id INT AUTO_INCREMENT PRIMARY KEY, + email VARCHAR(255) NOT NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + ) + `); + + const result = await connection.query( + 'INSERT INTO drivers_events_mariadb (email) VALUES (?)', + ['lin@example.com'] + ); + + const rows = await connection.query( + 'SELECT id, email FROM drivers_events_mariadb WHERE id = ?', + [result.insertId] + ); + + console.log(rows[0]); +} finally { + if (connection) connection.release(); + await pool.end(); +} +``` + +The connector uses Node.js trusted root CAs when `ssl: true` is enabled. If your runtime image does not ship with a current trust store, pass a CA bundle with `ssl: { ca: fs.readFileSync('./ca-bundle.crt') }`. + +# TLS and CA verification {% #tls %} + +Connections on Appwrite Cloud are encrypted with TLS, terminated at the edge and forwarded to your database over the internal network. Use certificate verification in production: + +| Driver | TLS option | +|--------------------------|-------------------------------------------------| +| `mysql2` | `ssl: { rejectUnauthorized: true }` | +| `mariadb` | `ssl: true` | +| Custom CA bundle | Add `ca` inside the driver's `ssl` object | + +The database hostname uses a certificate signed by a public CA, so Node.js can verify it with the built-in trust store in standard runtimes. Use a custom CA bundle only for images that do not include one, or when your organization requires a pinned bundle. + +For mTLS, where the client also presents a certificate, see the [Network security](/docs/products/databases/mysql/network-security) page. Add the client `key` and `cert` alongside `ca` in the same `ssl` object. + +# Pool sizing {% #pool-sizing %} + +Pool sizing is a connection budget. Each connection in `connectionLimit`, across every running instance, counts against your specification's connection cap. A single app server with `connectionLimit: 10` is usually modest. Ten replicas with `connectionLimit: 50` each can open 500 connections and exhaust smaller specifications. + +Size each driver pool to the connection cap divided by replica count, then leave headroom for migrations, background workers, and admin tools. If you need more client concurrency than the engine can accept directly, route runtime traffic through the [connection pooler](/docs/products/databases/mysql/connection-pooling). + +# Serverless connection management {% #serverless %} + +On Lambda, Cloud Run, Vercel, and similar platforms, every cold start is a fresh instance with its own pool. Keep the pool at module scope so warm invocations reuse it, and keep each pool small, usually `connectionLimit: 1` or `2`. + +Appwrite's MySQL pooler is ProxySQL on port `6033`. It is designed for high fan-out runtime traffic and defaults to transaction mode. In transaction mode, use text queries with placeholders through `query`, and keep server-side prepared statements, temporary tables, user variables, and named locks on the direct port (`3306`) or a session-mode pooler. + +Run migrations, schema changes, and dump or restore tools on the direct port. These workflows rely on a stable session and DDL privileges. + +# Troubleshooting {% #troubleshooting %} + +| Symptom | Cause and fix | +|----------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------| +| `self-signed certificate` / `unable to verify the first certificate` | TLS is reaching the wrong host, or the runtime has a stale or incomplete CA bundle. Verify the database hostname and supply a current public CA bundle only when the runtime lacks one. | +| `ER_CON_COUNT_ERROR` / connection attempts rejected at the proxy | Aggregate pool size across all instances exceeds the database specification's connection cap. Lower each pool's `connectionLimit`, or use the [connection pooler](/docs/products/databases/mysql/connection-pooling) on port `6033` with small per-instance pools. | +| `Unknown prepared statement handler` or prepared statement errors on port `6033` | A prepared statement cache is being used through the transaction-mode pooler. Use `query` with placeholders for pooled runtime traffic, or use the direct port or [session mode](/docs/products/databases/mysql/connection-pooling#modes). | +| `ETIMEDOUT` / `connect ETIMEDOUT` | The database may be cold-starting on smaller specifications or blocked by an [IP allowlist](/docs/products/databases/mysql/network-security#ip-allowlist). Confirm your egress IP is allowed and raise `connectTimeout` to absorb cold starts. | +| Connections drop after a period of inactivity | The proxy closes idle connections after its network idle timeout. Keep mysql2 `idleTimeout` below that window, and enable keep-alive where the driver supports it. | + +# Related {% #related %} + +{% cards %} +{% cards_item href="/docs/products/databases/mysql/connections" title="Connections" %} +Retrieve credentials, rotate the password, and connect with common clients. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/connection-pooling" title="Connection pooler" %} +Pool modes, ports, and read/write splitting for serverless workloads. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/quick-start#first-queries" title="SQL API" %} +Run SQL over HTTPS with no TCP connection for edge runtimes and scripts. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/network-security" title="Network security" %} +TLS, certificate verification, mTLS, and IP allowlists. +{% /cards_item %} +{% /cards %} diff --git a/src/routes/docs/products/databases/mysql/integrations/drizzle/+page.markdoc b/src/routes/docs/products/databases/mysql/integrations/drizzle/+page.markdoc new file mode 100644 index 00000000000..3f1caeb70de --- /dev/null +++ b/src/routes/docs/products/databases/mysql/integrations/drizzle/+page.markdoc @@ -0,0 +1,172 @@ +--- +layout: article +title: Drizzle +description: Use Drizzle ORM with an Appwrite native MySQL database. Configure mysql2, run migrations against the direct connection, and pool runtime traffic from serverless environments. +--- + +Appwrite's native MySQL database is a standard MySQL engine, so [Drizzle ORM](https://orm.drizzle.team/) works against it with no Appwrite-specific configuration. Point Drizzle's mysql2 driver at the connection string from the [Connections](/docs/products/databases/mysql/connections) page and use Drizzle Kit, the query builder, and the rest of the toolchain as you would against any MySQL server. + +{% info title="Before you start" %} +You'll need a native MySQL database in a `ready` state and its credentials. See [native MySQL databases](/docs/products/databases/mysql) to create one and [Connections](/docs/products/databases/mysql/connections) to retrieve the connection string. The primary user is `admin`, and the database name is generated per database. +{% /info %} + +# Set the connection string {% #connection-string %} + +Fetch the connection details with [`mysql.get()`](/docs/products/databases/mysql/connections#credentials), then put the returned connection string in your environment. Never commit it: + +```env +DATABASE_URL="mysql://admin:<password>@db-<hash>.<region>.appwrite.center:3306/<database>" +``` + +Connections on Appwrite Cloud are encrypted with TLS. If your runtime or mysql2 configuration does not infer TLS from the connection string, configure mysql2 to require TLS. See [Network security](/docs/products/databases/mysql/network-security) for TLS and network controls. + +# Install and configure the driver {% #driver %} + +Drizzle talks to MySQL through `mysql2`: + +```bash +npm install drizzle-orm mysql2 +npm install -D drizzle-kit +``` + +Import `drizzle` from `drizzle-orm/mysql2` and hand it the connection string: + +```ts +import { drizzle } from 'drizzle-orm/mysql2'; + +export const db = drizzle(process.env.DATABASE_URL!); +``` + +Define your tables in a schema file Drizzle Kit can read. Use the MySQL column builders from `drizzle-orm/mysql-core`: + +```ts +import { int, mysqlTable, timestamp, varchar } from 'drizzle-orm/mysql-core'; + +export const users = mysqlTable('users', { + id: int('id').primaryKey().autoincrement(), + email: varchar('email', { length: 255 }).notNull().unique(), + createdAt: timestamp('created_at').notNull().defaultNow() +}); +``` + +# Configure Drizzle Kit {% #config %} + +Drizzle Kit reads `drizzle.config.ts` for migrations and introspection. Set the `dialect`, point `schema` at your table definitions, and pass the connection string through `dbCredentials`: + +```ts +import { defineConfig } from 'drizzle-kit'; + +export default defineConfig({ + dialect: 'mysql', + schema: './src/schema.ts', + out: './drizzle', + dbCredentials: { + url: process.env.DATABASE_URL! + } +}); +``` + +# Run migrations {% #migrate %} + +Generate SQL migration files from your schema, then apply them: + +```bash +npx drizzle-kit generate +npx drizzle-kit migrate +``` + +`generate` diffs your schema against the last snapshot and writes a timestamped `.sql` file into the `out` directory. `migrate` applies any pending files to the database. Point Drizzle Kit at the direct engine port (`3306`), not the pooler, because migrations issue DDL that needs a session-level connection. The primary `admin` user owns the generated database and can run schema changes. + +For prototypes or preview databases where you do not need committed SQL migration files, Drizzle Kit can push the current schema directly: + +```bash +npx drizzle-kit push +``` + +To apply migrations from your application at startup instead of the CLI, use the mysql2 migrator: + +```ts +import { migrate } from 'drizzle-orm/mysql2/migrator'; +import { db } from './db'; + +await migrate(db, { migrationsFolder: './drizzle' }); +``` + +# Query with Drizzle {% #query %} + +Once the schema is migrated, use the query builder. The mysql2 dialect returns an insert result instead of the inserted row, so read the row back with the inserted ID: + +```ts +import { desc, eq } from 'drizzle-orm'; +import { db } from './db'; +import { users } from './schema'; + +const result = await db.insert(users).values({ email: 'ada@example.com' }); + +const [user] = await db.select().from(users).where(eq(users.id, Number(result[0].insertId))); + +const recent = await db + .select() + .from(users) + .orderBy(desc(users.createdAt)) + .limit(10); +``` + +On long-running servers, create the `db` instance once at module scope and reuse it. On serverless, keep a single instance per module scope so warm invocations reuse it, and use the pooler when your database specification includes it. + +# Pool connections from serverless {% #pooling %} + +Each running instance opens its own connections to the engine. On serverless and edge platforms such as Vercel, Netlify, and Cloudflare, short-lived instances can fan out into more backend connections than the engine allows. If your database specification includes the [connection pooler](/docs/products/databases/mysql/connection-pooling), route runtime traffic through it by connecting on port `6033` on the same hostname. + +Keep `drizzle.config.ts` and the startup migrator pointed at `DIRECT_URL` so DDL still runs over a session-level connection: + +```env +# Runtime: pooler port +DATABASE_URL="mysql://admin:<password>@db-<hash>.<region>.appwrite.center:6033/<database>" + +# Migrations & introspection: direct connection to the engine +DIRECT_URL="mysql://admin:<password>@db-<hash>.<region>.appwrite.center:3306/<database>" +``` + +```ts +import { defineConfig } from 'drizzle-kit'; + +export default defineConfig({ + dialect: 'mysql', + schema: './src/schema.ts', + out: './drizzle', + dbCredentials: { + url: process.env.DIRECT_URL! + } +}); +``` + +The pooler defaults to transaction mode, which does not keep a backend connection across statements. Drizzle's regular mysql2 query builder sends text queries and works with transaction pooling, but session-level features such as explicit prepared queries, user variables, and temporary tables need the direct port or a session-mode pooler. See the [pooler modes](/docs/products/databases/mysql/connection-pooling#modes) page for the trade-offs. + +# Use a branch for previews and CI {% #branches %} + +[Branches](/docs/products/databases/mysql/branches) are isolated copies of a database with their own hostname and connection string. They're ideal for running migrations against throwaway data in a pull-request preview or an integration-test job: + +1. Create a branch from the API and read its `connectionString`. +2. Export it as `DIRECT_URL` and `DATABASE_URL` for the preview or CI job. +3. Run `drizzle-kit migrate` or `drizzle-kit push`, then run your test suite against the branch. +4. Delete the branch when the job finishes. + +Because a branch starts from a storage snapshot, the schema and data match the source database at branch time, so migrations run against representative data without touching production. + +# Related {% #related %} + +{% cards %} +{% cards_item href="/docs/products/databases/mysql/connections" title="Connections" %} +Retrieve credentials and rotate the primary password. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/connection-pooling" title="Connection pooler" %} +Pool modes, ports, and read/write splitting for serverless workloads. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/branches" title="Branches" %} +Ephemeral database copies for preview environments and CI. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/network-security" title="Network security" %} +TLS and network controls for native MySQL databases. +{% /cards_item %} +{% /cards %} diff --git a/src/routes/docs/products/databases/mysql/integrations/ef-core/+page.markdoc b/src/routes/docs/products/databases/mysql/integrations/ef-core/+page.markdoc new file mode 100644 index 00000000000..2e74ff84805 --- /dev/null +++ b/src/routes/docs/products/databases/mysql/integrations/ef-core/+page.markdoc @@ -0,0 +1,178 @@ +--- +layout: article +title: EF Core +description: Use Entity Framework Core with an Appwrite native MySQL database. Configure the MySQL provider, run migrations against the direct MySQL host, and rely on the provider's connection pool from an ASP.NET server. +--- + +A native MySQL database is a standard MySQL engine, so [Entity Framework Core](https://learn.microsoft.com/ef/core/) works with it through a MySQL EF Core provider. Point the provider at the connection details from the [Connections](/docs/products/databases/mysql/connections) page, then use `DbContext`, migrations, and LINQ queries as you would with any MySQL server. + +{% info title="Before you start" %} +You'll need a native MySQL database in a `ready` state and its credentials. See [native MySQL databases](/docs/products/databases/mysql) to create one and [Connections](/docs/products/databases/mysql/connections) to retrieve the connection details. +{% /info %} + +# Install the provider {% #install %} + +Add Oracle's EF Core provider for MySQL, the EF Core design-time package, and the `dotnet-ef` CLI tool: + +```bash +dotnet add package MySql.EntityFrameworkCore +dotnet add package Microsoft.EntityFrameworkCore.Design +dotnet new tool-manifest +dotnet tool install dotnet-ef +``` + +Keep the MySQL provider and EF Core design package on the same major version as your app's EF Core packages. + +# Set the connection string {% #connection-string %} + +ADO.NET providers use key/value connection strings rather than a URL. Store the connection string in `appsettings.json` under `ConnectionStrings`, and keep the password out of source control with [user secrets](https://learn.microsoft.com/aspnet/core/security/app-secrets) or environment variables: + +```json +{ + "ConnectionStrings": { + "Default": "Server=db-<hash>.<region>.appwrite.center;Port=3306;Database=<database>;User=admin;Password=<password>;SslMode=Required" + } +} +``` + +The Appwrite MySQL host accepts TLS connections on port `3306`. `SslMode=Required` encrypts the connection. For full certificate and hostname verification, use `SslMode=VerifyFull`: + +```text +Server=db-<hash>.<region>.appwrite.center;Port=3306;Database=<database>;User=admin;Password=<password>;SslMode=VerifyFull +``` + +# Configure the DbContext {% #dbcontext %} + +Define your model and `DbContext`. The model is ordinary EF Core code, and the table name in this example is prefixed so it is easy to identify the objects created by the guide: + +```csharp +using Microsoft.EntityFrameworkCore; + +public class User +{ + public int Id { get; set; } + public string Email { get; set; } = string.Empty; + public DateTime CreatedAt { get; set; } = DateTime.UtcNow; +} + +public class AppDbContext : DbContext +{ + public AppDbContext(DbContextOptions<AppDbContext> options) + : base(options) + { + } + + public DbSet<User> Users => Set<User>(); + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity<User>(entity => + { + entity.ToTable("ef_core_users"); + entity.HasIndex(user => user.Email).IsUnique(); + entity.Property(user => user.Email).HasMaxLength(255).IsRequired(); + entity.Property(user => user.CreatedAt).HasDefaultValueSql("CURRENT_TIMESTAMP(6)"); + }); + } +} +``` + +# Register the provider {% #provider %} + +Register the `DbContext` in `Program.cs`, reading the connection string with `GetConnectionString`. Use `UseMySQL(...)` for Oracle's MySQL EF Core provider: + +```csharp +using Microsoft.EntityFrameworkCore; + +var builder = WebApplication.CreateBuilder(args); + +builder.Services.AddDbContext<AppDbContext>(options => + options.UseMySQL( + builder.Configuration.GetConnectionString("Default")!, + mySqlOptions => mySqlOptions.MigrationsHistoryTable("ef_core_migrations_history"))); +``` + +The `MigrationsHistoryTable` option keeps EF Core's migration tracking table prefixed with the rest of this guide's example objects. + +# Run migrations {% #migrate %} + +Migrations need a session connection and full DDL privileges, so run them against the direct MySQL host on port `3306`, not the [pooler](/docs/products/databases/mysql/connection-pooling). The primary `admin` user owns the database. + +Create the first migration, then apply it: + +```bash +dotnet tool run dotnet-ef migrations add InitialCreate +dotnet tool run dotnet-ef database update +``` + +`dotnet tool run dotnet-ef database update` reads the same `Default` connection string and applies any pending migrations. EF Core records applied migrations in the configured migration history table so it only applies new migrations next time. + +# Wire up an ASP.NET server {% #aspnet %} + +The route handlers use ordinary EF Core queries: + +```csharp +var app = builder.Build(); + +app.MapGet("/users", async (AppDbContext db) => + await db.Users.OrderByDescending(user => user.CreatedAt).Take(10).ToListAsync()); + +app.MapPost("/users", async (AppDbContext db, CreateUser request) => +{ + var user = new User { Email = request.Email }; + db.Users.Add(user); + await db.SaveChangesAsync(); + + return Results.Created($"/users/{user.Id}", user); +}); + +app.Run(); + +public record CreateUser(string Email); +``` + +# Connection pooling {% #pooling %} + +Connector/NET has connection pooling enabled by default. Each process keeps its own pool keyed on the connection string, so a long-running ASP.NET server usually connects directly to MySQL and tunes the provider pool with connection string options: + +```text +Server=db-<hash>.<region>.appwrite.center;Port=3306;Database=<database>;User=admin;Password=<password>;SslMode=Required;Max Pool Size=50 +``` + +Keep the sum across all your processes under the engine's connection limit for the database's specification. + +If you run many short-lived instances that each open their own provider pool, route runtime traffic through the Appwrite [connection pooler](/docs/products/databases/mysql/connection-pooling) on port `6033`: + +```text +Server=db-<hash>.<region>.appwrite.center;Port=6033;Database=<database>;User=admin;Password=<password>;SslMode=Required;Max Pool Size=20 +``` + +Keep migrations and administrative jobs on the direct port `3306`. The pooler defaults to **transaction mode**, which does not hold a backend connection across statements. If your application relies on session state such as server-side prepared statements, user variables, or temporary tables, switch the pooler to **session mode**, see the [pooler](/docs/products/databases/mysql/connection-pooling#modes) page for the trade-offs. + +# Use a branch for previews and CI {% #branches %} + +Database [branches](/docs/products/databases/mysql/branches) are isolated copies of a database with their own hostname and credentials. They're useful for running migrations against throwaway data in a pull-request preview or integration-test job: + +1. Create a branch from the API and read its connection details. +2. Build the connection string for the branch host and pass it as the `Default` connection string. +3. Run `dotnet tool run dotnet-ef database update` and your test suite against the branch. +4. Delete the branch when the job finishes. + +Because a branch starts from a storage snapshot, the schema and data match the source database at branch time, so migrations run against representative data without touching the source database. + +# Related {% #related %} + +{% cards %} +{% cards_item href="/docs/products/databases/mysql/connections" title="Connect" %} +Retrieve credentials, rotate the password, and create scoped connection users. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/connection-pooling" title="Connection pooler" %} +Pool modes, ports, and read/write splitting for serverless workloads. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/branches" title="Branches" %} +Ephemeral database copies for preview environments and CI. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/network-security" title="Network" %} +TLS modes, certificate verification, mTLS, and IP allowlists. +{% /cards_item %} +{% /cards %} diff --git a/src/routes/docs/products/databases/mysql/integrations/fastapi/+page.markdoc b/src/routes/docs/products/databases/mysql/integrations/fastapi/+page.markdoc new file mode 100644 index 00000000000..b5859571a30 --- /dev/null +++ b/src/routes/docs/products/databases/mysql/integrations/fastapi/+page.markdoc @@ -0,0 +1,193 @@ +--- +layout: article +title: FastAPI +description: Use FastAPI and SQLAlchemy 2.x with an Appwrite native MySQL database. Configure the async asyncmy engine, pass TLS through connect_args, inject a session per request, and run Alembic migrations against the direct database port. +--- + +An Appwrite native MySQL database is a standard MySQL engine, so [FastAPI](https://fastapi.tiangolo.com/) with [SQLAlchemy](https://docs.sqlalchemy.org/) and an async MySQL driver works against it with no Appwrite-specific runtime code. You point `create_async_engine` at the connection string from the [connections](/docs/products/databases/mysql/connections) page and use the SQLAlchemy ORM, the FastAPI dependency system, and Alembic the same way you would against any self-hosted MySQL server. + +{% info title="Before you start" %} +You'll need a native MySQL database in a `ready` state and its credentials. See [native MySQL databases](/docs/products/databases/mysql) to create one and [connections](/docs/products/databases/mysql/connections) to retrieve the connection string. The primary user is `admin`, and the database name is generated for each database. +{% /info %} + +# Install dependencies {% #install %} + +```bash +pip install "fastapi[standard]" "sqlalchemy[asyncio]" asyncmy alembic +``` + +# Set the connection string {% #connection-string %} + +Fetch the connection string with the [API](/docs/products/databases/mysql/connections#credentials). Put it in your environment, never commit it. SQLAlchemy's asyncmy dialect uses the `mysql+asyncmy://` scheme, so swap the leading `mysql://` for it and add `charset=utf8mb4`: + +```env +DATABASE_URL="mysql+asyncmy://admin:<password>@db-<hash>.<region>.appwrite.center:3306/<database>?charset=utf8mb4" +DATABASE_SSL=true +``` + +This guide uses the [asyncmy](https://github.com/long2ice/asyncmy) driver. SQLAlchemy also supports the async `mysql+aiomysql://` dialect, but the snippets below use `mysql+asyncmy://`. + +# Create the async engine {% #engine %} + +Cloud connections require TLS. Build an `ssl.SSLContext` and pass it through `connect_args`; use `DATABASE_SSL=false` only for a local MySQL server that does not offer TLS: + +```python +import ssl + +from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine + +connect_args = ( + {"ssl": ssl.create_default_context()} + if settings.database_ssl + else {} +) + +engine = create_async_engine( + settings.database_url, + connect_args=connect_args, + pool_size=10, + max_overflow=5, + pool_pre_ping=True, +) + +SessionLocal = async_sessionmaker(engine, expire_on_commit=False) +``` + +The server certificate is signed by a well-known public CA, so `ssl.create_default_context()` validates the certificate chain against the system trust store. See the [Network](/docs/products/databases/mysql/network-security) page for TLS and network access controls. + +# Define a model {% #model %} + +```python +from datetime import datetime + +from sqlalchemy import String, func +from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column + +class Base(DeclarativeBase): + pass + +class User(Base): + __tablename__ = "fastapi_users" + + id: Mapped[int] = mapped_column(primary_key=True) + email: Mapped[str] = mapped_column(String(255), unique=True) + created_at: Mapped[datetime] = mapped_column(server_default=func.now()) +``` + +SQLAlchemy renders the integer primary key as `AUTO_INCREMENT` for MySQL. The explicit `String(255)` keeps the unique email index within MySQL's indexed column limits. + +# Inject a session per request {% #session %} + +FastAPI's dependency system gives each request its own `AsyncSession` and closes it when the request finishes. Define a dependency that yields a session, then annotate path operations with it: + +```python +from typing import Annotated + +from fastapi import Depends, FastAPI +from sqlalchemy import select +from sqlalchemy.ext.asyncio import AsyncSession + +app = FastAPI() + +async def get_session(): + async with SessionLocal() as session: + yield session + +SessionDep = Annotated[AsyncSession, Depends(get_session)] + +@app.post("/users") +async def create_user(email: str, session: SessionDep): + user = User(email=email) + session.add(user) + await session.commit() + await session.refresh(user) + return user + +@app.get("/users") +async def list_users(session: SessionDep): + result = await session.scalars(select(User).order_by(User.created_at.desc())) + return result.all() +``` + +Create the engine once at module scope and reuse it for the whole process, the pool lives inside it. Don't open a new engine per request. + +# Run migrations {% #migrate %} + +Generate Alembic's async scaffold, which opens the connection asynchronously and hands a sync connection to the migration context: + +```bash +alembic init -t async migrations +``` + +Point `target_metadata` at `Base.metadata` in `migrations/env.py`, then autogenerate and apply: + +```bash +alembic revision --autogenerate -m "init" +alembic upgrade head +``` + +Review the generated migration before applying it. If the database contains tables that Alembic should not manage, configure Alembic's include filters or run the migration against a branch so autogenerate only emits changes for your FastAPI app. + +Run migrations against the **direct** engine port (`3306`), not the pooler. DDL needs a session-level connection, and Alembic's async template already uses a `NullPool`, so a fresh connection is opened and closed per run. The primary `admin` user owns the default database and can run schema changes. + +# Pool sizing {% #sizing %} + +A long-running `uvicorn` server holds a SQLAlchemy pool for its lifetime, so connect to the **direct** engine port (`3306`) with a sized pool. Keep `pool_size` multiplied by the number of server processes under the connection limit of your [specification](/docs/products/databases/mysql#specifications), and let `max_overflow` absorb short bursts: + +```python +engine = create_async_engine( + settings.database_url, + connect_args=connect_args, + pool_size=10, + max_overflow=5, + pool_pre_ping=True, +) +``` + +When the same app runs on a serverless platform (for example an Appwrite [function](/docs/products/functions)) where each invocation is a fresh instance, that can fan out into more backend connections than the engine allows. Route runtime traffic through the [connection pooler](/docs/products/databases/mysql/connection-pooling) on port `6033` instead, and avoid keeping another application pool on top of it: + +```env +DATABASE_URL="mysql+asyncmy://admin:<password>@db-<hash>.<region>.appwrite.center:6033/<database>?charset=utf8mb4" +DATABASE_SSL=true +``` + +```python +from sqlalchemy import NullPool + +engine = create_async_engine( + settings.database_url, + connect_args=connect_args, + poolclass=NullPool, + pool_pre_ping=True, +) +``` + +The pooler defaults to **transaction mode**, which returns the backend connection to the pool after each transaction. Use **session mode** if your application relies on session-level state such as user variables, temporary tables, or server-side prepared statements, see the [pooler](/docs/products/databases/mysql/connection-pooling#modes) page for the trade-offs. + +# Use a branch for previews and CI {% #branches %} + +[Branches](/docs/products/databases/mysql/branches) are instant, isolated copies of a database with their own hostname and connection string. They're ideal for running migrations against throwaway data in a pull-request preview or an integration-test job: + +1. Create a branch from the API and read its `connectionString`. +2. Rewrite the scheme to `mysql+asyncmy://`, add `charset=utf8mb4`, and export it as `DATABASE_URL`. +3. Run `alembic upgrade head` against the branch's direct port, then your test suite. +4. Delete the branch when the job finishes. + +Because a branch starts from a storage snapshot, the schema and data match the source database at branch time, so migrations run against representative data without touching production. + +# Related {% #related %} + +{% cards %} +{% cards_item href="/docs/products/databases/mysql/connections" title="Connections" %} +Retrieve credentials and rotate the primary password. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/connection-pooling" title="Connection pooler" %} +Pool modes, ports, and read/write splitting for serverless workloads. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/branches" title="Branches" %} +Ephemeral database copies for preview environments and CI. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/network-security" title="Network" %} +TLS modes, certificate verification, mTLS, and IP allowlists. +{% /cards_item %} +{% /cards %} diff --git a/src/routes/docs/products/databases/mysql/integrations/gorm/+page.markdoc b/src/routes/docs/products/databases/mysql/integrations/gorm/+page.markdoc new file mode 100644 index 00000000000..3cd1a6eba43 --- /dev/null +++ b/src/routes/docs/products/databases/mysql/integrations/gorm/+page.markdoc @@ -0,0 +1,217 @@ +--- +layout: article +title: GORM +description: Use GORM with an Appwrite native MySQL database in Go. Build the MySQL DSN, open a connection, size the database/sql pool, and run migrations with AutoMigrate or golang-migrate. +--- + +A native MySQL database is a standard MySQL engine, so [GORM](https://gorm.io/) talks to it through the regular MySQL driver. Build a go-sql-driver DSN from the credentials returned by Appwrite, hand it to `gorm.io/driver/mysql`, and use models, `AutoMigrate`, and the query API as you would against any MySQL server. + +{% info title="Before you start" %} +You'll need a native MySQL database in a `ready` state and its credentials. See [native MySQL databases](/docs/products/databases/mysql) to create one and [Connections](/docs/products/databases/mysql/connections) to retrieve the hostname, password, and generated database name. The primary user is `admin`. +{% /info %} + +# Build the DSN {% #dsn %} + +Keep the password out of source and read the connection details from the environment: + +```env +DB_HOST="db-<hash>.<region>.appwrite.center" +DB_PORT="3306" +DB_NAME="<database>" +DB_PASSWORD="<password>" +DB_TLS="true" +``` + +GORM's MySQL driver uses [go-sql-driver/mysql](https://github.com/go-sql-driver/mysql) DSNs. The wire format is `admin:<password>@tcp(db-<hash>.<region>.appwrite.center:3306)/<database>?parseTime=true&tls=true`. Use `mysql.Config` to format the DSN so passwords and database names are escaped correctly: + +```go +cfg := mysqlcfg.Config{ + User: "admin", + Passwd: os.Getenv("DB_PASSWORD"), + Net: "tcp", + Addr: net.JoinHostPort(os.Getenv("DB_HOST"), os.Getenv("DB_PORT")), + DBName: os.Getenv("DB_NAME"), + ParseTime: true, + TLSConfig: os.Getenv("DB_TLS"), +} + +dsn := cfg.FormatDSN() +``` + +`parseTime=true` lets the driver scan MySQL `DATE`, `DATETIME`, and `TIMESTAMP` values into Go `time.Time` values. Keep `DB_TLS=true` for Appwrite Cloud connections. Local development environments that terminate no TLS can set `DB_TLS=false`. + +For mTLS, see the [Network security](/docs/products/databases/mysql/network-security) page. + +# Open a connection {% #open %} + +Pass the DSN to `mysql.Open`, then call `gorm.Open`: + +```go +package main + +import ( + "fmt" + "net" + "os" + "time" + + mysqlcfg "github.com/go-sql-driver/mysql" + gormmysql "gorm.io/driver/mysql" + "gorm.io/gorm" +) + +type User struct { + ID uint `gorm:"primaryKey"` + Email string `gorm:"size:255;not null;uniqueIndex"` + CreatedAt time.Time +} + +func (User) TableName() string { + return "gorm_users" +} + +func main() { + cfg := mysqlcfg.Config{ + User: "admin", + Passwd: os.Getenv("DB_PASSWORD"), + Net: "tcp", + Addr: net.JoinHostPort(os.Getenv("DB_HOST"), os.Getenv("DB_PORT")), + DBName: os.Getenv("DB_NAME"), + ParseTime: true, + TLSConfig: os.Getenv("DB_TLS"), + } + + db, err := gorm.Open(gormmysql.Open(cfg.FormatDSN()), &gorm.Config{}) + if err != nil { + panic(err) + } + + if err := db.AutoMigrate(&User{}); err != nil { + panic(err) + } + + user := User{Email: fmt.Sprintf("ada+%d@example.com", time.Now().UnixNano())} + if err := db.Create(&user).Error; err != nil { + panic(err) + } + + var saved User + if err := db.First(&saved, "email = ?", user.Email).Error; err != nil { + panic(err) + } + + fmt.Println(saved.ID, saved.Email) +} +``` + +Connect to the direct engine port (`3306`) for a long-running server and cap the underlying pool yourself, see [pool sizing](#pool) below. If you route runtime traffic through the [connection pooler](/docs/products/databases/mysql/connection-pooling) on port `6033`, enable `InterpolateParams` in the driver config so placeholder values are sent as one text query in transaction mode: + +```go +cfg := mysqlcfg.Config{ + User: "admin", + Passwd: os.Getenv("DB_PASSWORD"), + Net: "tcp", + Addr: net.JoinHostPort(os.Getenv("DB_HOST"), "6033"), + DBName: os.Getenv("DB_NAME"), + ParseTime: true, + TLSConfig: os.Getenv("DB_TLS"), + InterpolateParams: true, +} + +db, err := gorm.Open(gormmysql.Open(cfg.FormatDSN()), &gorm.Config{}) +``` + +# Define a model and migrate {% #model %} + +Declare your models as Go structs and let GORM create the tables with `AutoMigrate`: + +```go +type User struct { + ID uint `gorm:"primaryKey"` + Email string `gorm:"size:255;not null;uniqueIndex"` + CreatedAt time.Time +} + +func (User) TableName() string { + return "gorm_users" +} + +if err := db.AutoMigrate(&User{}); err != nil { + panic(err) +} +``` + +`AutoMigrate` creates the table if it's missing and adds any missing columns and indexes. It does not drop columns or change existing column types, so it's convenient in development but not a substitute for versioned migrations in production. Run schema changes against the direct engine port because DDL needs a session-level connection. The primary `admin` user owns the generated database and can run schema changes. + +For versioned migrations, [golang-migrate](https://github.com/golang-migrate/migrate) runs ordered up/down files. Point it at the direct engine port: + +```bash +migrate -path ./migrations \ + -database "mysql://admin:$DB_PASSWORD@tcp($DB_HOST:$DB_PORT)/$DB_NAME?tls=$DB_TLS&x-migrations-table=gorm_schema_migrations" \ + up +``` + +# Size the connection pool {% #pool %} + +GORM manages a `database/sql` pool under the hood. A long-running Go server holds that pool for its whole lifetime, so connect to the direct engine port and cap the pool against the engine's connection limit. Reach the underlying `*sql.DB` with `db.DB()`: + +```go +sqlDB, err := db.DB() +if err != nil { + panic(err) +} + +sqlDB.SetMaxOpenConns(25) +sqlDB.SetMaxIdleConns(25) +sqlDB.SetConnMaxLifetime(time.Hour) +``` + +Keep the sum of `SetMaxOpenConns` across every instance below the specification's `maxConnections`. If you run many instances or a serverless runtime that opens a fresh pool per cold start, route runtime traffic through the [connection pooler](/docs/products/databases/mysql/connection-pooling) and keep each instance's pool small. The pooler multiplexes them onto a smaller set of backend connections. + +# Run SQL with GORM {% #sql %} + +Use GORM's raw SQL helpers when you need a query that is clearer as SQL than as model operations. MySQL uses `?` placeholders: + +```go +type Result struct { + Email string +} + +var result Result +if err := db.Raw( + "SELECT email FROM gorm_users WHERE email = ? LIMIT 1", + user.Email, +).Scan(&result).Error; err != nil { + panic(err) +} +``` + +The same connection rules apply: use the direct port for migrations and session-level features, and use the pooler for high fan-out runtime queries when your database specification includes it. + +# Use a branch for previews and CI {% #branches %} + +[Branches](/docs/products/databases/mysql/branches) are isolated copies of a database with their own hostname and connection string. They're ideal for running migrations against throwaway data in a pull-request preview or an integration-test job: + +1. Create a branch from the API and read its `connectionString`. +2. Export the branch host, password, and database name into the environment your tests read. +3. Run `migrate ... up` or `AutoMigrate`, then run your test suite against the branch's direct port. +4. Delete the branch when the job finishes. + +Because a branch starts from a storage snapshot, the schema and data match the source database at branch time, so migrations run against representative data without touching production. + +# Related {% #related %} + +{% cards %} +{% cards_item href="/docs/products/databases/mysql/connections" title="Connections" %} +Retrieve credentials and rotate the primary password. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/connection-pooling" title="Connection pooler" %} +Pool modes, ports, and read/write splitting for serverless workloads. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/branches" title="Branches" %} +Ephemeral database copies for preview environments and CI. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/network-security" title="Network security" %} +TLS and network controls for native MySQL databases. +{% /cards_item %} +{% /cards %} diff --git a/src/routes/docs/products/databases/mysql/integrations/grafana/+page.markdoc b/src/routes/docs/products/databases/mysql/integrations/grafana/+page.markdoc new file mode 100644 index 00000000000..3946eac362a --- /dev/null +++ b/src/routes/docs/products/databases/mysql/integrations/grafana/+page.markdoc @@ -0,0 +1,99 @@ +--- +layout: article +title: Grafana +description: Connect Grafana to an Appwrite native MySQL database as a data source and build dashboards. Configure the MySQL data source and provision it from YAML. +--- + +An Appwrite [native MySQL database](/docs/products/databases/mysql) exposes a standard managed MySQL 8.4 or 8.0 engine, so [Grafana](https://grafana.com/) connects to it through the built-in **MySQL data source** with no Appwrite-specific configuration. Point the data source at your database hostname, authenticate with your database credentials, and query your tables to build dashboards and alerts. + +{% info title="Before you start" %} +You'll need a native MySQL database in a `ready` state and its credentials. Call `mysql.get()` from the Appwrite API to read `hostname`, `connectionPort`, `connectionUser`, `connectionPassword`, and `connectionString`. The primary user is `admin`, and Appwrite generates the database name for each database. See [Connections](/docs/products/databases/mysql/connections) to retrieve the values. +{% /info %} + +# Protect dashboard credentials {% #credentials %} + +Grafana can execute any SQL allowed by the data source user. Keep panel queries read-only, avoid saving write statements in dashboards, and restrict network access to trusted Grafana hosts with an [IP allowlist](/docs/products/databases/mysql/network-security#ip-allowlist). If your deployment has a secondary MySQL user with only `SELECT` privileges, use that user for Grafana. + +# Choose a connection target {% #target %} + +Grafana holds its data source connections open for the lifetime of the process. Long-lived connections should use either the direct MySQL port `3306` or a [connection pooler](/docs/products/databases/mysql/connection-pooling) on port `6033` running in **session mode**. + +Do not point Grafana at the **transaction-mode** pooler. Transaction mode hands a backend connection back to the pool after every statement, which breaks the session assumptions Grafana relies on for connection reuse and prepared statements. For a typical dashboard workload the direct MySQL port is the simplest choice. See the [pooler modes](/docs/products/databases/mysql/connection-pooling#modes) page for the trade-offs. + +# Add the MySQL data source {% #data-source %} + +In Grafana, open **Connections** > **Data sources** > **Add data source** and select **MySQL**. Fill in the connection details using the values from your native MySQL database: + +| Field | Value | +| --- | --- | +| **Host URL** | `db-<hash>.<region>.appwrite.center:3306` | +| **Database** | `<database>` | +| **Username** | `admin` | +| **Password** | `<password>` | + +Regions are `fra`, `nyc`, `sfo`, `sgp`, `syd`, and `tor`. Appwrite Cloud encrypts connections to the public hostname with TLS. Grafana's MySQL data source uses MySQL-specific TLS fields such as `tlsAuthWithCACert`, `tlsSkipVerify`, and TLS certificate values in `secureJsonData`. + +If you use Grafana Cloud and restrict database access with an IP allowlist, add the Grafana Cloud outbound IP ranges for your stack to the database allowlist. Grafana Cloud can reach the public Appwrite database hostname directly. Private connectivity features are only needed when the database is on a private network. + +Under **Connection limits**, keep the connection counts modest so Grafana doesn't exhaust the engine's connection budget. **Max open** caps total connections from this Grafana instance, **Max idle** caps pooled idle connections, and **Max lifetime** recycles connections after the given number of seconds. Select **Save & test** to verify connectivity. + +# Provision from YAML {% #provisioning %} + +Instead of configuring the data source by hand, you can [provision](https://grafana.com/docs/grafana/latest/administration/provisioning/) it declaratively. Drop a file into Grafana's `provisioning/datasources/` directory and read the password from an environment variable so it never lands in source control: + +```yaml +apiVersion: 1 + +datasources: + - name: Appwrite native MySQL + type: mysql + url: db-<hash>.<region>.appwrite.center:3306 + user: admin + jsonData: + database: <database> + maxOpenConns: 5 + maxIdleConns: 2 + maxIdleConnsAuto: true + connMaxLifetime: 14400 + secureJsonData: + password: $GRAFANA_DB_PASSWORD + editable: false +``` + +The MySQL data source uses `type: mysql`, keeps the database name under `jsonData.database`, and reads the password from `secureJsonData.password`. Grafana expands `$GRAFANA_DB_PASSWORD` from the process environment when it loads the provisioning file. Add Grafana's MySQL TLS fields if your deployment requires explicit TLS configuration. See the [MySQL data source](https://grafana.com/docs/grafana/latest/datasources/mysql/configure/) docs for every available field. + +# Build a panel {% #panel %} + +With the data source connected, create a dashboard and add a panel backed by it. Switch the query editor to code mode and write a read-only query against your tables. For example, to plot daily sign-ups from a `grafana_users` table over time: + +```text +SELECT + CAST(DATE(created_at) AS DATETIME) AS time, + COUNT(*) AS signups +FROM grafana_users +GROUP BY CAST(DATE(created_at) AS DATETIME) +ORDER BY time; +``` + +Grafana maps the `time` column to the panel's time axis and `signups` to the value. MySQL 8.4 enables `ONLY_FULL_GROUP_BY`, so the selected time expression must match the grouped expression. + +# Related {% #related %} + +{% cards %} +{% cards_item href="/docs/products/databases/mysql" title="MySQL databases" %} +Overview of native MySQL database engines, versions, and regions. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/connections" title="Connect" %} +Retrieve credentials and rotate the primary password. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/connection-pooling" title="Connection pooler" %} +Pool modes and ports. Use the direct MySQL port or session mode for Grafana. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/network-security" title="Network" %} +TLS modes, certificate verification, and IP allowlists. +{% /cards_item %} +{% /cards %} + +{% arrow_link href="/docs/products/databases/mysql/connections" %} +Connect to a native MySQL database +{% /arrow_link %} diff --git a/src/routes/docs/products/databases/mysql/integrations/laravel/+page.markdoc b/src/routes/docs/products/databases/mysql/integrations/laravel/+page.markdoc new file mode 100644 index 00000000000..944c397c743 --- /dev/null +++ b/src/routes/docs/products/databases/mysql/integrations/laravel/+page.markdoc @@ -0,0 +1,215 @@ +--- +layout: article +title: Laravel +description: Use Laravel and Eloquent with an Appwrite native MySQL database. Configure the connection, run migrations against the direct port, and pool serverless traffic through the connection pooler. +--- + +A native MySQL database is a standard MySQL engine, so [Laravel](https://laravel.com/docs) works against it with no Appwrite-specific configuration. Point the `mysql` connection in `config/database.php` at the credentials from the [Connections](/docs/products/databases/mysql/connections) page, then use Eloquent, the query builder, migrations, and queues as you would against any MySQL server. + +{% info title="Before you start" %} +You'll need a native MySQL database in a `ready` state and its credentials. See [MySQL databases](/docs/products/databases/mysql) to create one. To retrieve credentials, call [`mysql.get()`](/docs/products/databases/mysql/connections#credentials) and use the returned hostname, port, username, password, and database name. The primary username is `admin`, and the database name is generated per database. +{% /info %} + +# Configure the connection {% #connection %} + +Laravel reads database credentials from `.env`. Fetch them with [`mysql.get()`](/docs/products/databases/mysql/connections#credentials), then set the matching connection. Never commit `.env`: + +```env +DB_CONNECTION=mysql +DB_HOST=db-<hash>.<region>.appwrite.center +DB_PORT=3306 +DB_DATABASE=<database> +DB_USERNAME=admin +DB_PASSWORD=<password> +DB_CHARSET=utf8mb4 +DB_COLLATION=utf8mb4_unicode_ci +``` + +The scaffolded `config/database.php` wires these variables into the `mysql` connection: + +```php +'mysql' => [ + 'driver' => 'mysql', + 'url' => env('DB_URL'), + 'host' => env('DB_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', '3306'), + 'database' => env('DB_DATABASE', 'laravel'), + 'username' => env('DB_USERNAME', 'root'), + 'password' => env('DB_PASSWORD', ''), + 'unix_socket' => env('DB_SOCKET', ''), + 'charset' => env('DB_CHARSET', 'utf8mb4'), + 'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'), + 'prefix' => '', + 'prefix_indexes' => true, + 'strict' => true, + 'engine' => null, + 'options' => extension_loaded('pdo_mysql') ? array_filter([ + Mysql::ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), + ]) : [], +], +``` + +Laravel imports `Pdo\Mysql` at the top of this file in new projects. Appwrite Cloud requires TLS on the public hostname. If your PHP runtime needs an explicit CA bundle for MySQL TLS verification, set `MYSQL_ATTR_SSL_CA` to a trusted root store path and keep the `options` entry in the `mysql` connection: + +```php +'options' => extension_loaded('pdo_mysql') ? array_filter([ + Mysql::ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), +]) : [], +``` + +# Run migrations {% #migrate %} + +Define your schema with a migration: + +```php +Schema::create('posts', function (Blueprint $table) { + $table->id(); + $table->string('title'); + $table->text('body'); + $table->timestamps(); +}); +``` + +Apply migrations from your machine or a deploy step: + +```bash +php artisan migrate + +# non-interactive, for CI and production deploys +php artisan migrate --force +``` + +Run `migrate` against the **direct** MySQL port (`3306`), not the pooler. Migrations issue DDL and schema inspection queries that should use a stable backend connection. The primary `admin` user owns the database and can run schema changes. + +# Query with Eloquent {% #query %} + +Once the schema is migrated, use Eloquent models and the query builder as usual: + +```php +namespace App\Models; + +use Illuminate\Database\Eloquent\Model; + +class Post extends Model +{ + protected $fillable = [ + 'title', + 'body', + ]; +} +``` + +```php +use App\Models\Post; + +$post = Post::create([ + 'title' => 'Hello from a native MySQL database', + 'body' => 'Stored in a native MySQL database.', +]); + +$recent = Post::query() + ->orderByDesc('created_at') + ->limit(10) + ->get(); +``` + +Nothing about the native MySQL database changes how Eloquent, relationships, transactions, or the query builder behave. It is a standard MySQL server behind a TLS connection. + +# Pool connections from serverless {% #pooling %} + +The right port depends on how your app runs. + +A **long-running** PHP process, traditional PHP-FPM with persistent connections, [Laravel Octane](https://laravel.com/docs/octane), or a queue worker, holds its own backend connection for its lifetime. Point these at the **direct** MySQL port (`3306`), or at the [connection pooler](/docs/products/databases/mysql/connection-pooling) in **session mode**. Don't put a long-lived process behind the transaction-mode pooler. + +A **serverless** or per-request deployment (Vercel, AWS Lambda, Cloud Run) opens a fresh connection on every invocation and can fan out into more backend connections than the engine allows. Route runtime traffic through the pooler's **transaction-mode** port (`6033`) on the same hostname, and keep a named direct connection for migrations and other schema operations: + +```env +# Runtime: pooled, transaction mode +DB_HOST=db-<hash>.<region>.appwrite.center +DB_PORT=6033 +DB_DATABASE=<database> +DB_USERNAME=admin +DB_PASSWORD=<password> +DB_CHARSET=utf8mb4 +DB_COLLATION=utf8mb4_unicode_ci + +# Migrations and schema operations: direct MySQL port +DB_DIRECT_HOST=db-<hash>.<region>.appwrite.center +DB_DIRECT_PORT=3306 +DB_DIRECT_DATABASE=<database> +DB_DIRECT_USERNAME=admin +DB_DIRECT_PASSWORD=<password> +``` + +Add a second MySQL connection in `config/database.php` for direct schema work: + +```php +'mysql_direct' => [ + 'driver' => 'mysql', + 'url' => env('DB_DIRECT_URL'), + 'host' => env('DB_DIRECT_HOST', env('DB_HOST', '127.0.0.1')), + 'port' => env('DB_DIRECT_PORT', env('DB_PORT', '3306')), + 'database' => env('DB_DIRECT_DATABASE', env('DB_DATABASE', 'laravel')), + 'username' => env('DB_DIRECT_USERNAME', env('DB_USERNAME', 'root')), + 'password' => env('DB_DIRECT_PASSWORD', env('DB_PASSWORD', '')), + 'unix_socket' => env('DB_SOCKET', ''), + 'charset' => env('DB_CHARSET', 'utf8mb4'), + 'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'), + 'prefix' => '', + 'prefix_indexes' => true, + 'strict' => true, + 'engine' => null, + 'options' => extension_loaded('pdo_mysql') ? array_filter([ + Mysql::ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), + ]) : [], +], +``` + +Run schema commands against that connection: + +```bash +php artisan migrate --database=mysql_direct --force +``` + +For manual schema work, call `DB::connection('mysql_direct')`. The transaction-mode pooler does not keep session state across transactions, so user variables, temporary tables, and server-side prepared statements should use the direct port or **session mode**. See the [pooler](/docs/products/databases/mysql/connection-pooling#modes) page for the trade-offs. + +# Queues and Horizon {% #queues %} + +A queue worker is a long-running process. `php artisan queue:work` boots once and processes jobs for its whole lifetime, holding a persistent database connection the entire time. The same applies to every worker that [Laravel Horizon](https://laravel.com/docs/horizon) supervises. Treat workers like any other long-lived process: + +- Connect them to the **direct** MySQL port (`3306`) or the **session-mode** pooler, never the transaction-mode pooler. +- Restart workers periodically with `--max-time` or `--max-jobs` so a fresh process reclaims memory and reopens its connection. Supervisor or Horizon restarts them automatically. + +```bash +php artisan queue:work --max-time=3600 --max-jobs=500 +``` + +Each worker counts as one backend connection, so size your worker pool (and Horizon's `maxProcesses`) against the connection budget of your [specification](/docs/products/databases/mysql). Horizon itself requires Redis for the queue backend; only your application's data connection touches the native MySQL database. + +# Use a branch for previews and CI {% #branches %} + +MySQL [branches](/docs/products/databases/mysql/branches) are instant, isolated copies of a database with their own hostname. Create them from the API for running migrations against throwaway data in a pull-request preview or an integration-test job: + +1. Create a branch from the API and read its connection details. +2. Export them as the `DB_*` variables for the job. +3. Run `php artisan migrate --force` and your test suite against the branch. +4. Delete the branch when the job finishes. + +Because a branch starts from a storage snapshot, the schema and data match the source database at branch time, so migrations and tests run against realistic data without touching production. + +# Related {% #related %} + +{% cards %} +{% cards_item href="/docs/products/databases/mysql/connections" title="Connect" %} +Retrieve credentials, rotate the password, and create scoped connection users. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/connection-pooling" title="Connection pooler" %} +Pool modes, ports, and read/write splitting for serverless workloads. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/branches" title="Branches" %} +Ephemeral database copies for preview environments and CI. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/network-security" title="Network" %} +TLS modes, certificate verification, mTLS, and IP allowlists. +{% /cards_item %} +{% /cards %} diff --git a/src/routes/docs/products/databases/mysql/integrations/metabase/+page.markdoc b/src/routes/docs/products/databases/mysql/integrations/metabase/+page.markdoc new file mode 100644 index 00000000000..6f93a1a2960 --- /dev/null +++ b/src/routes/docs/products/databases/mysql/integrations/metabase/+page.markdoc @@ -0,0 +1,78 @@ +--- +layout: article +title: Metabase +description: Connect Metabase to an Appwrite native MySQL database for analytics. Configure MySQL connection details, require TLS on Cloud, and build dashboards on a session-safe connection. +--- + +Appwrite's native MySQL database is a standard MySQL engine, so [Metabase](https://www.metabase.com/) can connect to it without an Appwrite-specific adapter. Add the database in Metabase, use the host and credentials from the [Connections](/docs/products/databases/mysql/connections) page, and Metabase will sync the schema so your team can build questions and dashboards. + +{% info title="Before you start" %} +You'll need a native MySQL database in a `ready` state and its credentials. Fetch them with [`mysql.get()`](/docs/products/databases/mysql/connections#credentials). The response includes `hostname`, `connectionPort`, `connectionUser`, `connectionPassword`, and `connectionString`. The primary user is `admin`, and the database name is generated per database. +{% /info %} + +# Choose credentials for Metabase {% #credentials %} + +Metabase connects with the MySQL user you provide. Use the least-privilege MySQL account available for analytics. A reporting account typically needs `SELECT` on the tables and views Metabase should query. The primary `admin` user returned by Appwrite can read and write data and schema, so reserve it for trusted Metabase instances. + +Metabase features such as model actions and editable table data need write privileges. Enable them only on a connection whose MySQL account has the specific write permissions that workflow needs. + +# Add the database in Metabase {% #add-database %} + +In Metabase, click the grid icon, then open **Admin > Databases > Add a database**. Choose **MySQL** as the database type and fill in the connection form with the values from the [Connections](/docs/products/databases/mysql/connections) page. + +| Field | Value | +|-------|-------| +| Host | `db-<hash>.<region>.appwrite.center` | +| Port | `3306` | +| Database name | `<database>` | +| Username | `admin`, or your least-privilege MySQL account | +| Password | `<password>` | + +Turn on **Use a secure connection (SSL)**. Appwrite Cloud requires TLS for native MySQL connections on the public hostname. If your Metabase deployment needs an explicit certificate chain, add it in Metabase's **SSL certificate** field. See [Network security](/docs/products/databases/mysql/network-security) for Appwrite TLS and network controls. + +{% info title="Use a session-safe connection" %} +Metabase keeps database sessions open and can use session-level MySQL behavior while exploring data. Connect it to the direct MySQL port (`3306`). If your specification includes the [connection pooler](/docs/products/databases/mysql/connection-pooling), use `session` mode for Metabase. Transaction-mode pooling can break session-level features because a client session is not bound to one backend connection. +{% /info %} + +Click **Save changes**. Metabase verifies the connection and starts its first schema sync. + +# Build a question or dashboard {% #build %} + +Once the first sync finishes, your tables appear in the data picker. To build your first chart: + +1. Click **+ New > Question** and pick your Appwrite MySQL database as the data source. +2. Choose a table, add a summary such as count, sum, or average, and group by a column such as a timestamp. +3. Switch the visualization to a line, bar, or table view, then save the question. +4. Add saved questions to a dashboard and use filters to slice data across cards. + +Use read-only native SQL questions for analytics dashboards. If the connection uses `admin`, use Metabase permissions to limit who can run native SQL or enable write-capable features. + +# How Metabase syncs your schema {% #sync %} + +After you connect, Metabase scans the database to discover tables, columns, constraints, and field metadata, then keeps that metadata current on a schedule: + +- A lightweight schema sync runs hourly by default. +- A more intensive field-value scan runs daily by default to populate filter dropdowns. + +New tables and columns appear after the next sync. To pull them in immediately, open **Admin > Databases > your database** and click **Sync database schema**. You can also restrict which schemas Metabase tracks and adjust the sync and scan cadence from the database settings. Refer to the [Metabase documentation](https://www.metabase.com/docs/latest/databases/sync-scan) for the full set of sync and scan options. + +# Use a branch for testing {% #branches %} + +[Branches](/docs/products/databases/mysql/branches) are isolated copies of a native MySQL database with their own host and credentials. Point a second Metabase database connection at a branch when you want to validate a dashboard against a snapshot of production data without querying the live database. Branches are managed through the API, and you can delete the branch when testing is complete. + +# Related {% #related %} + +{% cards %} +{% cards_item href="/docs/products/databases/mysql" title="MySQL" %} +Provision and manage a native MySQL database for your project. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/connections" title="Connections" %} +Retrieve connection details and rotate the primary password. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/connection-pooling" title="Connection pooling" %} +Pool modes and ports, including why BI tools need session or direct connections. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/network-security" title="Network security" %} +TLS, certificate verification, IP allowlists, and idle connection timeouts. +{% /cards_item %} +{% /cards %} diff --git a/src/routes/docs/products/databases/mysql/integrations/nextjs/+page.markdoc b/src/routes/docs/products/databases/mysql/integrations/nextjs/+page.markdoc new file mode 100644 index 00000000000..74385b46e73 --- /dev/null +++ b/src/routes/docs/products/databases/mysql/integrations/nextjs/+page.markdoc @@ -0,0 +1,204 @@ +--- +layout: article +title: Next.js +description: Connect a Next.js App Router application to an Appwrite native MySQL database from Route Handlers, Server Actions, and Server Components, pool from serverless, and fall back to the SQL API on the Edge runtime. +--- + +An Appwrite native MySQL database works with standard MySQL drivers and ORMs, so a [Next.js](https://nextjs.org/) App Router application can query it from server-side code. Point your driver at the connection string from the [Connections](/docs/products/databases/mysql/connections) page and keep all database access on the server. + +{% info title="Before you start" %} +You'll need a native MySQL database in a `ready` state and its credentials. See [MySQL](/docs/products/databases/mysql) to create one and [Connections](/docs/products/databases/mysql/connections) to retrieve the connection string. The primary user is `admin`, and Appwrite generates the database name for each database. +{% /info %} + +# Where to connect {% #where %} + +In the App Router, every server-side execution context runs on the **Node.js runtime by default**, and the Node.js runtime can open raw TCP sockets. That means you can use a standard database driver from any of these: + +- **Route Handlers** (`app/api/.../route.ts`) for public routes, webhooks, and REST-style APIs. +- **Server Actions** (`'use server'` functions) for form submissions and app-internal mutations. +- **Server Components** (`async` components) for read queries that render straight into the page. + +Never import a database driver into a Client Component (`'use client'`) or ship the connection string to the browser. Keep all database access on the server. + +The one exception is the **Edge runtime** (`export const runtime = 'edge'`), which runs in a constrained environment and cannot use Node.js TCP drivers. If a route opts into Edge, use the [SQL API](/docs/products/databases/mysql/quick-start#first-queries) over HTTPS, see [the Edge runtime section](#edge) below. + +# Install the driver {% #install %} + +Install the MySQL driver for Node.js: + +```bash +npm install mysql2 +``` + +# Environment variables {% #env %} + +Put the connection strings in your environment and never commit them. For local development, use `.env.local`, which Next.js loads automatically and the default `create-next-app` template excludes from Git: + +```env +DATABASE_URL="mysql://admin:<password>@db-<hash>.<region>.appwrite.center:6033/<database>" +DIRECT_URL="mysql://admin:<password>@db-<hash>.<region>.appwrite.center:3306/<database>" +MYSQL_SSL="true" +``` + +`DATABASE_URL` points at the [connection pooler](/docs/products/databases/mysql/connection-pooling) port (`6033`) for runtime traffic, and `DIRECT_URL` points at the MySQL engine port (`3306`) for migrations and schema changes. The connection string returned by Appwrite uses the engine port, so change only the port when you connect through the pooler. If your specification does not include the pooler, use the direct connection string for `DATABASE_URL` too. + +Appwrite Cloud serves MySQL over TLS. The examples below use `MYSQL_SSL="true"` to make `mysql2` request TLS and verify the server certificate with the runtime's trusted CAs. For full certificate verification controls or mTLS, see the [Network security](/docs/products/databases/mysql/network-security) page. + +# Create a table for the examples {% #table %} + +Run this SQL once through your migration workflow or the `mysql` client: + +```sql +CREATE TABLE IF NOT EXISTS nextjs_users ( + id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + email VARCHAR(255) NOT NULL UNIQUE, + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP +); + +INSERT INTO nextjs_users (email) +VALUES ('ada@example.com') +ON DUPLICATE KEY UPDATE email = nextjs_users.email; +``` + +# Pool serverless connections {% #pooling %} + +When you deploy to Vercel, Netlify, or another serverless platform, each invocation can spin up a fresh instance with its own connection pool. Hundreds of concurrent invocations fan out into far more backend connections than the engine allows. Route runtime traffic through the [connection pooler](/docs/products/databases/mysql/connection-pooling) on the pooler port so it can multiplex those instances over a small number of backend connections. + +The pooler defaults to **transaction mode**, which does not keep a backend connection across statements, so session-level features such as server-side prepared statements and temporary tables are unavailable. Use `pool.query()` with `?` placeholders for pooled runtime queries. Reserve the engine port for migrations, schema changes, and workloads that need a full session. + +# Use a singleton client {% #singleton %} + +Instantiate one pool per module scope and reuse it across invocations, so warm serverless instances do not reconnect on every request. In development, Next.js hot reload re-evaluates modules, which can leak connections, so cache the pool on `globalThis`. + +With [mysql2](https://sidorares.github.io/node-mysql2/): + +```ts +// lib/db.ts +import mysql, { type Pool } from 'mysql2/promise'; + +const globalForDb = globalThis as unknown as { mysqlPool?: Pool }; + +function createPool() { + const url = new URL(process.env.DATABASE_URL!); + + return mysql.createPool({ + host: url.hostname, + port: Number(url.port || 3306), + user: decodeURIComponent(url.username), + password: decodeURIComponent(url.password), + database: decodeURIComponent(url.pathname.slice(1)), + waitForConnections: true, + connectionLimit: 5, + ssl: process.env.MYSQL_SSL === 'true' ? { rejectUnauthorized: true } : undefined + }); +} + +export const pool = globalForDb.mysqlPool ?? createPool(); + +if (process.env.NODE_ENV !== 'production') globalForDb.mysqlPool = pool; +``` + +Query it from a Server Component or Route Handler: + +```ts +// app/users/route.ts +import type { RowDataPacket } from 'mysql2'; + +import { pool } from '@/lib/db'; + +type UserRow = RowDataPacket & { + id: number; + email: string; + created_at: Date; +}; + +export async function GET() { + const [users] = await pool.query<UserRow[]>( + 'SELECT id, email, created_at FROM nextjs_users ORDER BY created_at DESC LIMIT ?', + [10] + ); + + return Response.json(users); +} +``` + +# Use Prisma or Drizzle {% #orm %} + +For a typed schema, migrations, and a query builder, reach for an ORM. Both integrate with the pooled `DATABASE_URL` plus direct `DIRECT_URL` pattern above. + +- **Prisma**: point the runtime at the pooled connection string and keep the Prisma CLI on the engine port for migrations, then run `prisma migrate deploy`. See the [Prisma](/docs/products/databases/mysql/integrations/prisma) guide for the full config and migration flow. +- **Drizzle**: use Drizzle's MySQL driver for runtime queries and the direct URL for `drizzle-kit` migrations. See the [Drizzle](/docs/products/databases/mysql/integrations/drizzle) guide. + +{% arrow_link href="/docs/products/databases/mysql/integrations/prisma" %} +Set up Prisma against native MySQL +{% /arrow_link %} + +# Edge runtime: use the SQL API {% #edge %} + +If a Route Handler or route segment opts into the Edge runtime, it cannot use a Node.js MySQL driver: + +```ts +export const runtime = 'edge'; +``` + +From the Edge runtime, you can execute one parameterized SQL statement over HTTPS and get JSON back. `SELECT`, `INSERT`, `UPDATE`, and `DELETE` statements are allowed by default. Use the global `fetch` available in the Edge runtime: + +```ts +// app/edge-users/route.ts +export const runtime = 'edge'; + +export async function GET() { + const response = await fetch( + 'https://<REGION>.cloud.appwrite.io/v1/mysql/<DATABASE_ID>/executions', + { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'X-Appwrite-Project': process.env.APPWRITE_PROJECT_ID!, + 'X-Appwrite-Key': process.env.APPWRITE_API_KEY! + }, + body: JSON.stringify({ + sql: 'SELECT id, email FROM nextjs_users WHERE created_at > ? ORDER BY created_at DESC LIMIT ?', + bindings: ['2026-05-01 00:00:00', 10] + }) + } + ); + + if (!response.ok) { + throw new Error(await response.text()); + } + + const { rows } = await response.json(); + return Response.json(rows); +} +``` + +The response is `{ rows, rowCount, columns, durationMs, truncated, bytes }`. Bindings are sent separately and never interpolated into the SQL string. Add `APPWRITE_PROJECT_ID` and `APPWRITE_API_KEY` to your environment alongside the database URLs. Use an API key with the `dedicatedDatabases.execute` scope. + +{% arrow_link href="/docs/products/databases/mysql/quick-start#first-queries" %} +Read the SQL API reference +{% /arrow_link %} + +# Local development {% #local %} + +`next dev` runs on the Node.js runtime, so a local server can connect to the native MySQL database with the same server-only driver code. Keep `DATABASE_URL`, `DIRECT_URL`, and `MYSQL_SSL` in `.env.local`. + +For throwaway data in tests or experiments, create a [branch](/docs/products/databases/mysql/branches), an instant, isolated copy with its own connection string, and point `.env.local` at it. Delete the branch when you're done. + +# Deploy {% #deploy %} + +When you deploy, set the same `DATABASE_URL`, `DIRECT_URL`, `MYSQL_SSL`, `APPWRITE_PROJECT_ID`, and `APPWRITE_API_KEY` as environment variables on your hosting platform. Run migrations from the direct connection in your build or release step, and use the SQL API from any Edge Functions. + +# Related {% #related %} + +{% cards %} +{% cards_item href="/docs/products/databases/mysql/integrations/prisma" title="Prisma" %} +Datasource config, pooled and direct URLs, and the migration workflow. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/quick-start#first-queries" title="SQL API" %} +Query over HTTPS from the Edge runtime without a TCP connection. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/connection-pooling" title="Connection pooler" %} +Pool modes, ports, and read/write splitting for serverless workloads. +{% /cards_item %} +{% /cards %} diff --git a/src/routes/docs/products/databases/mysql/integrations/prisma/+page.markdoc b/src/routes/docs/products/databases/mysql/integrations/prisma/+page.markdoc new file mode 100644 index 00000000000..3db720058bd --- /dev/null +++ b/src/routes/docs/products/databases/mysql/integrations/prisma/+page.markdoc @@ -0,0 +1,214 @@ +--- +layout: article +title: Prisma +description: Use Prisma ORM with an Appwrite native MySQL database. Configure the Prisma 7 datasource, apply schema changes through the direct connection, and instantiate Prisma Client with the MySQL driver adapter. +--- + +[Prisma ORM](https://www.prisma.io/) works with Appwrite's native MySQL database as a standard MySQL target. Configure Prisma with the connection string from Appwrite, apply schema changes through the direct database connection, and use Prisma Client from your application code. + +{% info title="Before you start" %} +You'll need a native MySQL database in a `ready` state and its credentials. The database object returned by the Appwrite API includes `hostname`, `connectionUser`, `connectionPassword`, and `connectionString`; you can read it with `mysql.get()` or from the response when you create the database. +{% /info %} + +# Initialize Prisma {% #initialize %} + +Install Prisma, Prisma Client, the MySQL driver adapter, the MariaDB driver used by the adapter, and the TypeScript tools used by the examples: + +```bash +npm install -D prisma typescript tsx @types/node +npm install @prisma/client @prisma/adapter-mariadb dotenv mariadb +``` + +Initialize Prisma for MySQL: + +```bash +npx prisma init --datasource-provider mysql --output ../generated/prisma +``` + +Prisma 7 generates a `prisma.config.ts` file and a `prisma/schema.prisma` file. Set `"type": "module"` in `package.json` if your project does not already use ECMAScript modules. + +# Configure connection strings {% #connection-strings %} + +Store the Appwrite connection string in environment variables and do not commit it: + +```env +DATABASE_URL="mysql://admin:<password>@db-<hash>.<region>.appwrite.center:3306/<database>?sslaccept=strict" +DIRECT_URL="mysql://admin:<password>@db-<hash>.<region>.appwrite.center:3306/<database>?sslaccept=strict" +``` + +`DATABASE_URL` is the runtime connection used by Prisma Client. `DIRECT_URL` is the direct database connection used by Prisma CLI commands. + +Appwrite Cloud uses TLS for MySQL connections. Prisma's MySQL connector uses `sslaccept=strict` for TLS with certificate verification. For mTLS and network controls, see [Network security](/docs/products/databases/mysql/network-security). + +Prisma's `migrate dev` command uses a shadow database to detect drift. Appwrite's MySQL `admin` user is scoped to its database and cannot create another MySQL database for that workflow. Generate development migrations against a local MySQL database, a separate Appwrite database, or an Appwrite branch, then apply committed migrations to this database with `migrate deploy`. + +# Configure Prisma {% #configure-prisma %} + +In `prisma.config.ts`, read the CLI connection string from the environment: + +```ts +import "dotenv/config"; +import { defineConfig } from "prisma/config"; + +export default defineConfig({ + schema: "prisma/schema.prisma", + migrations: { + path: "prisma/migrations", + seed: "tsx prisma/seed.ts", + }, + datasource: { + url: process.env["DIRECT_URL"] ?? process.env["DATABASE_URL"], + }, +}); +``` + +In `prisma/schema.prisma`, keep the datasource provider in the schema file and generate Prisma Client into the output directory created by `prisma init`: + +```prisma +generator client { + provider = "prisma-client" + output = "../generated/prisma" +} + +datasource db { + provider = "mysql" +} + +model User { + id String @id @default(uuid()) + email String @unique + createdAt DateTime @default(now()) + + @@map("prisma_User") +} +``` + +Rename the mapped table for your application. If you are connecting to an existing database, use Prisma introspection after you configure the environment variables so your schema matches the current tables. + +# Pool connections from serverless {% #pooling %} + +Prisma Client opens database connections from each running application instance. On serverless platforms, many cold starts can quickly multiply the number of backend MySQL connections. On specifications that include the [connection pooler](/docs/products/databases/mysql/connection-pooling), route runtime traffic through the pooler port, `6033`, for `DATABASE_URL` while keeping `DIRECT_URL` on the direct MySQL port, `3306`, for migrations and introspection: + +```env +# Runtime: pooled connection through the Appwrite connection pooler +DATABASE_URL="mysql://admin:<password>@db-<hash>.<region>.appwrite.center:6033/<database>?sslaccept=strict" + +# Prisma CLI: direct MySQL connection for migrations and introspection +DIRECT_URL="mysql://admin:<password>@db-<hash>.<region>.appwrite.center:3306/<database>?sslaccept=strict" +``` + +The pooler defaults to transaction mode, which gives the highest connection multiplexing. If your application depends on session-level features such as user variables, temporary tables, or session-scoped prepared statements, use session mode or keep that workload on the direct MySQL port. See [Connection pooling](/docs/products/databases/mysql/connection-pooling#modes) for pool mode trade-offs. + +# Apply schema changes {% #schema-changes %} + +For an initial migration generated from the Prisma schema file, create a migration directory and write the SQL diff: + +```bash +mkdir -p prisma/migrations/20260708160000_init +npx prisma migrate diff --from-empty --to-schema prisma/schema.prisma --script --output prisma/migrations/20260708160000_init/migration.sql +``` + +If this database already contains tables and Prisma has not created its migration history, baseline it once before applying migrations: + +```bash +mkdir -p prisma/migrations/00000000000000_baseline +touch prisma/migrations/00000000000000_baseline/migration.sql +npx prisma migrate resolve --applied 00000000000000_baseline +``` + +Apply committed migrations through the direct MySQL connection: + +```bash +npx prisma migrate deploy +``` + +Generate Prisma Client after you install dependencies or change `prisma/schema.prisma`: + +```bash +npx prisma generate +``` + +The primary `admin` user owns its assigned database and can run schema changes inside that database. Keep migrations and introspection on the direct MySQL port because they need session-level behavior. + +# Seed data {% #seed %} + +With the seed command configured in `prisma.config.ts`, add a seed script: + +```ts +import "dotenv/config"; +import { PrismaMariaDb } from "@prisma/adapter-mariadb"; +import { PrismaClient } from "../generated/prisma/client"; + +const adapter = new PrismaMariaDb(process.env.DATABASE_URL!); +const prisma = new PrismaClient({ adapter }); + +await prisma.user.upsert({ + where: { email: "ada@example.com" }, + update: {}, + create: { email: "ada@example.com" }, +}); + +await prisma.$disconnect(); +``` + +Run the seed command: + +```bash +npx prisma db seed +``` + +# Query with Prisma Client {% #query %} + +Instantiate Prisma Client with the MySQL driver adapter: + +```ts +import "dotenv/config"; +import { PrismaMariaDb } from "@prisma/adapter-mariadb"; +import { PrismaClient } from "./generated/prisma/client"; + +const adapter = new PrismaMariaDb(process.env.DATABASE_URL!); +const prisma = new PrismaClient({ adapter }); + +const user = await prisma.user.create({ + data: { email: "grace@example.com" }, +}); + +const recent = await prisma.user.findMany({ + orderBy: { createdAt: "desc" }, + take: 10, +}); + +console.log({ user, recent }); + +await prisma.$disconnect(); +``` + +On long-running servers, instantiate `PrismaClient` once and reuse it. On serverless platforms, keep a single client per module scope so warm invocations reuse it, and rely on the pooler to absorb cold-start connection churn when your database specification includes it. + +# Use a branch for previews and CI {% #branches %} + +[Branches](/docs/products/databases/mysql/branches) are instant, isolated copies of a database with their own hostname and connection string. They are useful for running migrations against throwaway data in a pull-request preview or integration-test job: + +1. Create a branch from the API and read its `connectionString`. +2. Export it as `DIRECT_URL`, and use the pooled variant as `DATABASE_URL` if the branch has the pooler enabled. +3. Run `npx prisma migrate deploy` and your test suite against the branch. +4. Delete the branch when the job finishes. + +Because a branch starts from a storage snapshot, the schema and data match the source database at branch time, so migrations run against realistic data without touching production. + +# Related {% #related %} + +{% cards %} +{% cards_item href="/docs/products/databases/mysql/connections" title="Connections" %} +Retrieve credentials, rotate the primary password, and connect with MySQL tools. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/connection-pooling" title="Connection pooling" %} +Pool modes, ports, and read/write splitting for serverless workloads. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/branches" title="Branches" %} +Ephemeral database copies for preview environments and CI. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/network-security" title="Network security" %} +TLS modes, certificate verification, mTLS, and IP allowlists. +{% /cards_item %} +{% /cards %} diff --git a/src/routes/docs/products/databases/mysql/integrations/rails/+page.markdoc b/src/routes/docs/products/databases/mysql/integrations/rails/+page.markdoc new file mode 100644 index 00000000000..325fd3228c8 --- /dev/null +++ b/src/routes/docs/products/databases/mysql/integrations/rails/+page.markdoc @@ -0,0 +1,173 @@ +--- +layout: article +title: Rails +description: Use Ruby on Rails and ActiveRecord with an Appwrite native MySQL database. Configure database.yml, run migrations against the direct database port, and size the ActiveRecord pool. +--- + +A native MySQL database is a standard MySQL engine, so [Ruby on Rails](https://rubyonrails.org/) works against it through ActiveRecord with no Appwrite-specific configuration. Point `config/database.yml` at the connection details from the [Connections](/docs/products/databases/mysql/connections) page and use ActiveRecord, migrations, and the rest of the Rails toolchain exactly as you would against any MySQL server. + +{% info title="Before you start" %} +You'll need a native MySQL database in a `ready` state and its credentials. Call `mysql.get()` from the Appwrite API to read `hostname`, `connectionUser`, `connectionPassword`, and `connectionString`. The primary user is `admin`, and Appwrite generates the database name for each database. +{% /info %} + +# Install the database driver {% #driver %} + +ActiveRecord talks to MySQL through the `mysql2` driver gem. Add it to your `Gemfile`: + +```ruby +# Gemfile +gem "mysql2", "~> 0.5" +``` + +The `mysql2` gem builds against MySQL client libraries, so the MySQL or MariaDB client headers must be available at install time. + +Then install: + +```bash +bundle install +``` + +# Set the connection string {% #connection-string %} + +Fetch the connection string with the [API](/docs/products/databases/mysql/connections#credentials). Keep it in an environment variable and do not commit it: + +```env +DATABASE_URL="mysql://admin:<password>@db-<hash>.<region>.appwrite.center:3306/<database>" +DB_SSL_MODE="required" +``` + +Rails maps the `mysql://` URL scheme to the `mysql2` adapter by default. Set `ssl_mode` in `database.yml` so mysql2 requires TLS on Appwrite Cloud. For certificate verification (`verify_identity`) or mTLS, see the [Network](/docs/products/databases/mysql/network-security) page. + +# Configure database.yml {% #database-yml %} + +Rails reads `DATABASE_URL` automatically. The simplest configuration points the `url` at the environment variable and lets ActiveRecord parse the host, port, database, and credentials out of it: + +```yaml +# config/database.yml +production: + adapter: mysql2 + url: <%= ENV["DATABASE_URL"] %> + ssl_mode: <%= ENV.fetch("DB_SSL_MODE", "required") %> + max_connections: <%= ENV.fetch("RAILS_MAX_THREADS", 5) %> +``` + +If you'd rather set the fields explicitly, the discrete keys map one-to-one to the values from the [Connections](/docs/products/databases/mysql/connections#credentials) response. Use ERB to read each value from the environment so no secret lands in source control: + +```yaml +# config/database.yml +production: + adapter: mysql2 + encoding: utf8mb4 + host: <%= ENV["DB_HOST"] %> # db-<hash>.<region>.appwrite.center + port: <%= ENV.fetch("DB_PORT", 3306) %> + database: <%= ENV["DB_NAME"] %> # <database> + username: <%= ENV.fetch("DB_USER", "admin") %> + password: <%= ENV["DB_PASSWORD"] %> + ssl_mode: <%= ENV.fetch("DB_SSL_MODE", "required") %> + max_connections: <%= ENV.fetch("RAILS_MAX_THREADS", 5) %> +``` + +When both `DATABASE_URL` and explicit keys are present, Rails merges them. `ssl_mode` and `max_connections` can still be set in `database.yml`, so a `url`-based config can keep secrets in the environment and tune the connection pool in YAML. + +# Size the connection pool {% #pool %} + +ActiveRecord manages a per-process connection pool. In current Rails apps, `max_connections:` caps how many backend connections a single Rails process holds. Older apps may use the `pool:` name for the same setting. The value defaults to `5` and must be large enough for every thread that checks out a connection, your Puma worker threads plus any background job threads in the same process. + +```yaml +production: + adapter: mysql2 + url: <%= ENV["DATABASE_URL"] %> + ssl_mode: <%= ENV.fetch("DB_SSL_MODE", "required") %> + max_connections: <%= ENV.fetch("RAILS_MAX_THREADS", 5) %> +``` + +Tying `max_connections` to `RAILS_MAX_THREADS` keeps it aligned with Puma's thread count. Each Puma **worker** is a separate process with its own pool, so the backend connection count is roughly `max_connections × workers × server instances`. Keep that product within your specification's `maxConnections`, see [specifications](/docs/products/databases/mysql#specifications). + +# Run migrations {% #migrate %} + +Generate and apply migrations the usual way: + +```bash +bin/rails db:migrate +``` + +Migrations issue DDL and need a session-level connection, so run them against the direct MySQL port `3306`, not the transaction-mode pooler. Point `DATABASE_URL` (or a separate migration URL) at the direct port when you run `db:migrate`. The primary `admin` user owns the database and can run schema changes. + +# Use ActiveRecord {% #activerecord %} + +Once `database.yml` is configured, models work with no further setup. Define a migration and model, then query through ActiveRecord: + +```ruby +# db/migrate/20240101000000_create_rails_users.rb +class CreateRailsUsers < ActiveRecord::Migration[8.1] + def change + create_table :rails_users do |t| + t.string :email, null: false + t.timestamps + end + add_index :rails_users, :email, unique: true + end +end +``` + +```ruby +# app/models/rails_user.rb +class RailsUser < ApplicationRecord + validates :email, presence: true, uniqueness: true +end +``` + +```ruby +RailsUser.create!(email: 'ada@example.com') + +recent = RailsUser.order(created_at: :desc).limit(10) +``` + +ActiveRecord opens connections lazily and reuses them from the pool, so a long-running Puma server keeps a small, stable set of backend connections rather than opening one per request. + +# Pooling for a long-running server {% #pooling %} + +A Rails app under Puma is a long-running process: it holds an ActiveRecord pool for its lifetime. That pairs naturally with the direct MySQL port `3306`, sized so `max_connections × workers` stays within your connection budget. This is the recommended setup for a persistent server. + +If you instead route through the [connection pooler](/docs/products/databases/mysql/connection-pooling) to absorb spikes or many app instances, prefer **session mode**, which keeps a backend connection for the whole client session and behaves like a direct connection to ActiveRecord. The pooler defaults to **transaction mode**, which hands out a different backend connection per transaction. If your Rails configuration enables server-side prepared statements, disable them for transaction-mode pooling or use session mode: + +```yaml +production: + adapter: mysql2 + url: <%= ENV["DATABASE_URL"] %> # pooler host, port 6033 + ssl_mode: <%= ENV.fetch("DB_SSL_MODE", "required") %> + max_connections: <%= ENV.fetch("RAILS_MAX_THREADS", 5) %> + prepared_statements: false +``` + +See the [pooler](/docs/products/databases/mysql/connection-pooling#modes) page for the mode trade-offs. Whichever runtime connection you choose, always run `bin/rails db:migrate` against the direct MySQL port. + +# Use a branch for previews and CI {% #branches %} + +[Branches](/docs/products/databases/mysql/branches) are instant, isolated copies of a database with their own hostname and connection string. They're ideal for running migrations against throwaway data in a pull-request preview or an integration-test job: + +1. Create a branch from the API and read its `connectionString`. +2. Export it as `DATABASE_URL` for the job. +3. Run `bin/rails db:migrate` and your test suite against the branch. +4. Delete the branch when the job finishes. + +A branch has no pooler and exposes the MySQL port directly, which gives migrations the session-level connection they need. Because a branch starts from a storage snapshot, the schema and data match the source database at branch time, so migrations run against realistic data without touching production. + +# Related {% #related %} + +{% cards %} +{% cards_item href="/docs/products/databases/mysql/connections" title="Connections" %} +Retrieve credentials and rotate the primary password. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/connection-pooling" title="Connection pooler" %} +Pool modes, ports, and read/write splitting for high-concurrency workloads. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/branches" title="Branches" %} +Ephemeral database copies for preview environments and CI. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/network-security" title="Network" %} +TLS modes, certificate verification, mTLS, and IP allowlists. +{% /cards_item %} +{% /cards %} + +For ActiveRecord and migration details beyond this guide, see the [Rails configuration guide](https://guides.rubyonrails.org/configuring.html). diff --git a/src/routes/docs/products/databases/mysql/integrations/retool/+page.markdoc b/src/routes/docs/products/databases/mysql/integrations/retool/+page.markdoc new file mode 100644 index 00000000000..d29e7d9fb3d --- /dev/null +++ b/src/routes/docs/products/databases/mysql/integrations/retool/+page.markdoc @@ -0,0 +1,89 @@ +--- +layout: article +title: Retool +description: Connect Retool to an Appwrite native MySQL database to build internal and admin tools. Fetch connection details with the API, configure the MySQL resource with TLS, and allow Retool Cloud network access when needed. +--- + +An Appwrite [native MySQL database](/docs/products/databases/mysql) exposes a standard MySQL connection, so [Retool](https://retool.com/) connects to it through the built-in **MySQL** resource. Use the database hostname, generated database name, and credentials from Appwrite, then build queries, tables, and forms in Retool for dashboards and admin panels. + +{% info title="Before you start" %} +You'll need a native MySQL database in a `ready` state, an Appwrite API key with `databases.read`, and permission to create resources in Retool. Fetch connection details by calling `mysql.get()`, which returns `hostname`, `connectionPort`, `connectionUser`, `connectionPassword`, and `connectionString`. See [Connections](/docs/products/databases/mysql/connections) for the full flow. +{% /info %} + +# Choose credentials {% #credentials %} + +The primary user is `admin`, and the database name is generated for each database. The connection string has this form: `mysql://admin:<password>@db-<hash>.<region>.appwrite.center:3306/<database>`. + +Use the returned `admin` credentials for the Retool resource and keep access limited through Retool resource permissions, Appwrite network controls, TLS, and narrowly scoped queries. Retool stores resource credentials server-side, so app users query through the Retool resource instead of connecting to MySQL from the browser. + +# Create the MySQL resource {% #resource %} + +In Retool, go to **Resources**, click **Create new** > **Resource**, search for `MySQL`, and select the MySQL tile. Give the resource a clear **Name** and optional **Description** that identifies the Appwrite database and environment. + +In **Resource credentials**, either paste the Appwrite connection string or fill in the fields manually: + +| Retool setting | Value | +|----------------|-------| +| Host | `db-<hash>.<region>.appwrite.center` | +| Port | `3306` | +| Database name | `<database>` | +| Connection options | Optional MySQL query parameters, such as `timezone=UTC` or `connectTimeout=10000` | +| Authentication | **Username and password** | +| Username | `admin` | +| Password | The value from `connectionPassword` | + +In **Advanced options**, choose an outbound region if your Retool organization uses regional egress and you want the resource traffic to originate near your Appwrite database. + +Enable **SSL/TLS**. Appwrite Cloud terminates TLS at the edge, and the certificate is signed by a public CA. If Retool shows **Reject unauthorized**, keep it enabled. If Retool shows **Verification mode**, choose **Full verification**. Leave **CA certificate** empty. + +Click **Test connection**. If the test succeeds, click **Create resource**. + +# Pick the connection path {% #connection-path %} + +For most Retool apps, connect directly to MySQL on port `3306`. Appwrite's MySQL pooler listens on port `6033` only on specifications that include connection pooling. If your database has the [connection pooler](/docs/products/databases/mysql/connection-pooling) enabled and your Retool queries rely on session-level state such as server-side prepared statements, user variables, or temporary tables, configure the pooler in **session** mode for that Retool resource. + +{% arrow_link href="/docs/products/databases/mysql/connection-pooling#modes" %} +Compare pooler modes +{% /arrow_link %} + +# Allow Retool Cloud through the network {% #network %} + +If you enabled an [IP allowlist](/docs/products/databases/mysql/network-security#ip-allowlist) for the database, add the Retool Cloud egress addresses for the resource's outbound region. Retool's default outbound region is `us-west-2`, and Retool also documents `eu-central-1` and `ap-southeast-1` egress addresses. Retrieve the current list from [Retool's IP address documentation](https://docs.retool.com/data-sources/reference/ip-allowlist-cloud-orgs) instead of copying static addresses into your runbook. + +If you leave the database allowlist open, rely on TLS, database credentials, and Retool resource permissions to protect access. + +{% arrow_link href="/docs/products/databases/mysql/network-security#ip-allowlist" %} +Configure the IP allowlist +{% /arrow_link %} + +# Build an admin tool {% #build %} + +After the resource is connected, create MySQL queries in Retool and wire them to components: + +- Use **SQL mode** for read queries that feed a **Table**, chart, or other display component. +- Use **GUI mode** actions such as **Insert a record**, **Update an existing record**, **Update a record, or create a new record if it doesn't exist**, **Delete a record**, **Bulk insert records**, **Bulk update via a primary key**, and **Bulk upsert via a primary key** for forms, imports, and editable tables. +- Bind table edits to the **Save changes** event and refresh the read query after writes complete. +- Show a confirmation modal before delete actions. + +Reference component values with Retool's `{{ }}` embedded expressions. Retool converts MySQL queries to prepared statements by default, which separates values from SQL text and helps prevent SQL injection. Keep that protection enabled unless you have a specific, reviewed reason to disable it. + +# Use a branch for staging {% #branches %} + +[Branches](/docs/products/databases/mysql/branches) are API-created, isolated copies of a MySQL database with their own connection details. Create a branch for staging or preview work, fetch its `connectionString`, and configure a second Retool MySQL resource against that branch. Delete the branch when the staging tool is no longer needed. + +# Related {% #related %} + +{% cards %} +{% cards_item href="/docs/products/databases/mysql" title="MySQL" %} +Create and manage a native MySQL database. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/connections" title="Connections" %} +Retrieve credentials and rotate the primary password. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/network-security" title="Network security" %} +TLS, IP allowlists, and other network controls. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/branches" title="Branches" %} +Create isolated database copies for staging and preview environments. +{% /cards_item %} +{% /cards %} diff --git a/src/routes/docs/products/databases/mysql/integrations/spring-boot/+page.markdoc b/src/routes/docs/products/databases/mysql/integrations/spring-boot/+page.markdoc new file mode 100644 index 00000000000..983119888a8 --- /dev/null +++ b/src/routes/docs/products/databases/mysql/integrations/spring-boot/+page.markdoc @@ -0,0 +1,182 @@ +--- +layout: article +title: Spring Boot +description: Connect a Spring Boot application to an Appwrite native MySQL database with Spring Data JPA and Hibernate. Configure the JDBC datasource and HikariCP pool, map entities, and run Flyway or Liquibase migrations against MySQL. +--- + +An Appwrite native MySQL database is a standard MySQL engine, so a Spring Boot application connects to it through MySQL Connector/J with no Appwrite-specific runtime configuration. Point `spring.datasource` at the JDBC URL from your database credentials, size the built-in HikariCP pool, and use Spring Data JPA, Hibernate, Flyway, or Liquibase as you would with any managed MySQL server. + +{% info title="Before you start" %} +You'll need a native MySQL database in a `ready` state and its credentials. You can fetch credentials with the API by calling `mysql.get()`, which returns `hostname`, `connectionUser`, `connectionPassword`, and `connectionString`. See [Connections](/docs/products/databases/mysql/connections) for the full flow. +{% /info %} + +# Add the dependencies {% #dependencies %} + +A Spring Data JPA application needs the JPA starter and MySQL Connector/J. HikariCP ships with `spring-boot-starter-data-jpa`, and Spring Boot picks the driver class from the JDBC URL. + +```text +org.springframework.boot:spring-boot-starter-data-jpa +com.mysql:mysql-connector-j +``` + +If you use Flyway, add `org.springframework.boot:spring-boot-starter-flyway` and `org.flywaydb:flyway-mysql`. If you use Liquibase, add `org.springframework.boot:spring-boot-starter-liquibase`. + +# Configure the datasource {% #datasource %} + +Build the JDBC URL from the host and database name in the credentials returned by `mysql.get()`. Appwrite uses port `3306`, the primary user is `admin`, and the database name is generated per database. Read the password from the environment: + +```yaml +spring: + datasource: + url: jdbc:mysql://db-<hash>.<region>.appwrite.center:3306/<database>?sslMode=REQUIRED + username: admin + password: ${DB_PASSWORD} + hikari: + maximum-pool-size: 10 + minimum-idle: 2 + connection-timeout: 30000 + max-lifetime: 1200000 + jpa: + hibernate: + ddl-auto: validate +``` + +The equivalent `application.properties`: + +```ini +spring.datasource.url=jdbc:mysql://db-<hash>.<region>.appwrite.center:3306/<database>?sslMode=REQUIRED +spring.datasource.username=admin +spring.datasource.password=${DB_PASSWORD} +spring.datasource.hikari.maximum-pool-size=10 +spring.datasource.hikari.minimum-idle=2 +spring.datasource.hikari.connection-timeout=30000 +spring.datasource.hikari.max-lifetime=1200000 +spring.jpa.hibernate.ddl-auto=validate +``` + +`sslMode=REQUIRED` enables TLS for the MySQL connection. If your security policy requires host certificate validation, configure MySQL Connector/J with `sslMode=VERIFY_IDENTITY` and a JVM trust configuration that trusts the certificate chain. The [Network security](/docs/products/databases/mysql/network-security) page covers TLS, mTLS, and IP allowlists. + +# Size the HikariCP pool {% #pool %} + +A Spring Boot server is long-running, so it holds its HikariCP pool open for the lifetime of the process. Keep `maximum-pool-size` modest. HikariCP guidance is that throughput usually peaks at a small pool, roughly `(CPU cores x 2) + effective spindle count` for the database, not hundreds of connections. A pool that exceeds what MySQL can serve only queues work inside the database and adds latency. + +Each replica of your application opens its own pool, so multiply `maximum-pool-size` by the number of instances and keep the total under the connection budget of your native MySQL database [specification](/docs/products/databases/mysql#specifications). Set `max-lifetime` a little below your infrastructure's idle timeout so HikariCP recycles connections before they are closed. + +# Map an entity {% #entity %} + +Define a JPA entity and a Spring Data repository as usual. This example uses a prefixed table name so it is easy to identify in a shared database: + +```java +package com.example.demo; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; + +@Entity +@Table(name = "spring_boot_users") +public class User { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false, unique = true) + private String email; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } +} +``` + +```java +package com.example.demo; + +import java.util.Optional; + +import org.springframework.data.jpa.repository.JpaRepository; + +public interface UserRepository extends JpaRepository<User, Long> { + Optional<User> findByEmail(String email); +} +``` + +Inject the repository wherever you need it and call `save`, `findById`, `findByEmail`, and the rest of the generated query methods. HikariCP hands each transaction a pooled connection and returns it on commit. + +# Run migrations {% #migrate %} + +Let a migration tool own the schema and set `ddl-auto: validate` so Hibernate checks the mapping against the live tables at startup but never alters them. Add Flyway or Liquibase to your build and Spring Boot runs pending migrations automatically on boot. + +For example, a Flyway migration at `src/main/resources/db/migration/V1__init.sql` can create the table used by the entity above: + +```sql +CREATE TABLE spring_boot_users ( + id BIGINT AUTO_INCREMENT PRIMARY KEY, + email VARCHAR(255) NOT NULL UNIQUE +); +``` + +Flyway reads versioned scripts from `src/main/resources/db/migration`. Point Flyway at the direct MySQL port `3306` so migrations run on a session connection with DDL privileges. Setting `spring.flyway.url` gives Flyway its own datasource, independent of the runtime pool: + +```ini +spring.flyway.url=jdbc:mysql://db-<hash>.<region>.appwrite.center:3306/<database>?sslMode=REQUIRED +spring.flyway.user=admin +spring.flyway.password=${DB_PASSWORD} +``` + +Liquibase is equivalent: it reads a changelog from `src/main/resources/db/changelog` and accepts its own `spring.liquibase.url`, `spring.liquibase.user`, and `spring.liquibase.password` pointing at the same MySQL port. + +The primary `admin` user owns the database and can run schema changes, so run migrations as `admin`. + +# Pooling and the connection pooler {% #pooling %} + +HikariCP is already a connection pool, so a long-running Spring Boot server should connect to the direct MySQL port `3306` and let HikariCP manage connections. Routing a server's traffic through the [connection pooler](/docs/products/databases/mysql/connection-pooling) in `transaction` mode stacks HikariCP on top of a transaction pooler and can break session-level features such as server-side prepared statements, user variables, and temporary tables. + +If you put the pooler in front of your server, use `session` mode so MySQL keeps a backend connection for the whole client session. Connect HikariCP on the pooler port `6033` and keep `maximum-pool-size` small. See the [connection pooler](/docs/products/databases/mysql/connection-pooling#modes) page for the mode trade-offs. Always run Flyway or Liquibase against port `3306` regardless of how runtime traffic connects. + +# Use a branch for previews and CI {% #branches %} + +[Branches](/docs/products/databases/mysql/branches) are instant, isolated copies of a database with their own hostname and connection string. They are useful for running migrations against throwaway data in a pull-request preview or integration-test job. + +1. Create a branch with the API and read its `connectionString`. +2. Convert the connection string to a JDBC URL and inject it into `spring.datasource.url`, or split it into `spring.datasource.url`, `spring.datasource.username`, and `spring.datasource.password`. +3. Boot the application so Flyway or Liquibase applies migrations, then run your test suite against the branch. +4. Delete the branch when the job finishes. + +Because a branch starts from a storage snapshot, the schema and data match the source database at branch time, so migrations and `@DataJpaTest` integration tests run against representative data without touching production. + +# Related {% #related %} + +{% cards %} +{% cards_item href="/docs/products/databases/mysql/connections" title="Connections" %} +Retrieve credentials and rotate the primary password. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/connection-pooling" title="Connection pooler" %} +Pool modes, ports, and read/write splitting for the connection pooler. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/branches" title="Branches" %} +Ephemeral database copies for preview environments and CI. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/network-security" title="Network security" %} +TLS modes, certificate verification, mTLS, and IP allowlists. +{% /cards_item %} +{% /cards %} + +{% arrow_link href="/docs/products/databases/mysql" %} +Back to native MySQL overview +{% /arrow_link %} diff --git a/src/routes/docs/products/databases/mysql/maintenance/+page.markdoc b/src/routes/docs/products/databases/mysql/maintenance/+page.markdoc new file mode 100644 index 00000000000..9dc6fd110e3 --- /dev/null +++ b/src/routes/docs/products/databases/mysql/maintenance/+page.markdoc @@ -0,0 +1,642 @@ +--- +layout: article +title: Maintenance +description: Maintenance windows, online engine version upgrades, pause and resume, and the lifecycle states of your MySQL database. +--- + +Appwrite manages the infrastructure around your database: security patches, engine upgrades, and instance health. This page covers the controls you have over when and how that maintenance happens. + +# Maintenance window {% #window %} + +Routine maintenance that can briefly affect the database runs inside a weekly window that you choose. Set it through the API by picking a day and start hour (UTC): + +{% multicode %} +```server-nodejs +import { Client, Mysql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +await mysql.updateMaintenance({ + databaseId: '<DATABASE_ID>', + day: 'sun', + hourUtc: 3, +}); +``` +```server-deno +import { Client, Mysql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +await mysql.updateMaintenance({ + databaseId: '<DATABASE_ID>', + day: 'sun', + hourUtc: 3, +}); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Mysql; + +$client = (new Client()) + ->setEndpoint('https://cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$mysql = new Mysql($client); + +$mysql->updateMaintenance( + databaseId: '<DATABASE_ID>', + day: 'sun', + hourUtc: 3, +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.mysql import Mysql + +client = Client() +client.set_endpoint('https://cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +mysql = Mysql(client) + +mysql.update_maintenance( + database_id='<DATABASE_ID>', + day='sun', + hour_utc=3, +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +mysql = Mysql.new(client) + +mysql.update_maintenance( + database_id: '<DATABASE_ID>', + day: 'sun', + hour_utc: 3, +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Mysql mysql = new Mysql(client); + +await mysql.UpdateMaintenance( + databaseId: "<DATABASE_ID>", + day: "sun", + hourUtc: 3 +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Mysql mysql = Mysql(client); + +await mysql.updateMaintenance( + databaseId: '<DATABASE_ID>', + day: 'sun', + hourUtc: 3, +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Mysql + +val client = Client() + .setEndpoint("https://cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val mysql = Mysql(client) + +mysql.updateMaintenance( + databaseId = "<DATABASE_ID>", + day = "sun", + hourUtc = 3, +) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let mysql = Mysql(client) + +_ = try await mysql.updateMaintenance( + databaseId: "<DATABASE_ID>", + day: "sun", + hourUtc: 3 +) +``` +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewMysql(client) + + _, err := service.UpdateMaintenance("<DATABASE_ID>", "sun", 3) + if err != nil { + panic(err) + } +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::mysql::Mysql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let mysql = Mysql::new(&client); + + mysql.update_maintenance("<DATABASE_ID>", "sun", 3).await?; + + Ok(()) +} +``` +```bash +curl -X PATCH \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <YOUR_API_KEY>" \ + -H "Content-Type: application/json" \ + -d '{ + "day": "sun", + "hourUtc": 3 + }' \ + https://cloud.appwrite.io/v1/mysql/<DATABASE_ID>/maintenance +``` +{% /multicode %} + +`day` accepts `sun` through `sat`, and `hourUtc` accepts `0` to `23`. + +# Engine version upgrades {% #upgrades %} + +You can upgrade the MySQL version online, such as from 8.0 to 8.4. A second instance is provisioned on the target version, data streams over with logical replication, and traffic cuts over once replication has caught up, with no read or write outage. The target version must be newer than the database's current version: + +{% multicode %} +```server-nodejs +import { Client, Mysql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +await mysql.createUpgrade({ + databaseId: '<DATABASE_ID>', + targetVersion: '8.4', +}); +``` +```server-deno +import { Client, Mysql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +await mysql.createUpgrade({ + databaseId: '<DATABASE_ID>', + targetVersion: '8.4', +}); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Mysql; + +$client = (new Client()) + ->setEndpoint('https://cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$mysql = new Mysql($client); + +$mysql->createUpgrade( + databaseId: '<DATABASE_ID>', + targetVersion: '8.4', +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.mysql import Mysql + +client = Client() +client.set_endpoint('https://cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +mysql = Mysql(client) + +mysql.create_upgrade( + database_id='<DATABASE_ID>', + target_version='8.4', +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +mysql = Mysql.new(client) + +mysql.create_upgrade( + database_id: '<DATABASE_ID>', + target_version: '8.4', +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Mysql mysql = new Mysql(client); + +await mysql.CreateUpgrade( + databaseId: "<DATABASE_ID>", + targetVersion: "8.4" +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Mysql mysql = Mysql(client); + +await mysql.createUpgrade( + databaseId: '<DATABASE_ID>', + targetVersion: '8.4', +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Mysql + +val client = Client() + .setEndpoint("https://cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val mysql = Mysql(client) + +mysql.createUpgrade( + databaseId = "<DATABASE_ID>", + targetVersion = "8.4", +) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let mysql = Mysql(client) + +_ = try await mysql.createUpgrade( + databaseId: "<DATABASE_ID>", + targetVersion: "8.4" +) +``` +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewMysql(client) + + _, err := service.CreateUpgrade("<DATABASE_ID>", "8.4") + if err != nil { + panic(err) + } +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::mysql::Mysql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let mysql = Mysql::new(&client); + + mysql.create_upgrade("<DATABASE_ID>", "8.4").await?; + + Ok(()) +} +``` +```bash +curl -X POST \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <YOUR_API_KEY>" \ + -H "Content-Type: application/json" \ + -d '{ + "targetVersion": "8.4" + }' \ + https://cloud.appwrite.io/v1/mysql/<DATABASE_ID>/upgrades +``` +{% /multicode %} + +# Pause and resume {% #pause-resume %} + +A paused database stops its compute but keeps its storage, configuration, and credentials. Pause a database you are not using to stop paying for compute; resume it when you need it again. From the API, update the status: + +{% multicode %} +```server-nodejs +import { Client, Mysql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +await mysql.update({ + databaseId: '<DATABASE_ID>', + status: 'paused', +}); +``` +```server-deno +import { Client, Mysql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +await mysql.update({ + databaseId: '<DATABASE_ID>', + status: 'paused', +}); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Mysql; + +$client = (new Client()) + ->setEndpoint('https://cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$mysql = new Mysql($client); + +$mysql->update( + databaseId: '<DATABASE_ID>', + status: 'paused', +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.mysql import Mysql + +client = Client() +client.set_endpoint('https://cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +mysql = Mysql(client) + +mysql.update( + database_id='<DATABASE_ID>', + status='paused', +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +mysql = Mysql.new(client) + +mysql.update( + database_id: '<DATABASE_ID>', + status: 'paused', +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Mysql mysql = new Mysql(client); + +await mysql.Update( + databaseId: "<DATABASE_ID>", + status: "paused" +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Mysql mysql = Mysql(client); + +await mysql.update( + databaseId: '<DATABASE_ID>', + status: 'paused', +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Mysql + +val client = Client() + .setEndpoint("https://cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val mysql = Mysql(client) + +mysql.update( + databaseId = "<DATABASE_ID>", + status = "paused", +) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let mysql = Mysql(client) + +_ = try await mysql.update( + databaseId: "<DATABASE_ID>", + status: "paused" +) +``` +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" + "github.com/appwrite/sdk-for-go/mysql" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewMysql(client) + + _, err := service.Update( + "<DATABASE_ID>", + mysql.WithUpdateStatus("paused"), + ) + if err != nil { + panic(err) + } +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::mysql::Mysql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let mysql = Mysql::new(&client); + + mysql.update("<DATABASE_ID>", None, Some("paused"), None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None).await?; + + Ok(()) +} +``` +```bash +curl -X PATCH \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <YOUR_API_KEY>" \ + -H "Content-Type: application/json" \ + -d '{ + "status": "paused" + }' \ + https://cloud.appwrite.io/v1/mysql/<DATABASE_ID> +``` +{% /multicode %} + +Set `status` back to `ready` to resume. Both transitions are asynchronous: the request returns immediately and the database moves through `pausing` or `resuming` before settling. A database in the `failed` state can also be recovered by setting its status to `ready`. + +# Lifecycle states {% #states %} + +| Status | Meaning | +|----------------|------------------------------------------------------------------| +| `provisioning` | Being created | +| `ready` | Online and accepting connections | +| `scaling` | A configuration or specification change is being applied | +| `pausing` | Transitioning to paused | +| `paused` | Compute stopped, storage retained | +| `resuming` | Transitioning back to ready | +| `restoring` | A backup or point-in-time restore is in progress | +| `failed` | An infrastructure error occurred; the database can be resumed | + +# Deleting a database {% #delete %} + +Delete a database programmatically or from the databases list in the Console. Deletion stops billing and invalidates the credentials immediately. Deleting a database also deletes its backups, so export anything you need first. diff --git a/src/routes/docs/products/databases/mysql/monitoring/+page.markdoc b/src/routes/docs/products/databases/mysql/monitoring/+page.markdoc new file mode 100644 index 00000000000..125beea074f --- /dev/null +++ b/src/routes/docs/products/databases/mysql/monitoring/+page.markdoc @@ -0,0 +1,215 @@ +--- +layout: article +title: Monitoring +description: Check database health, watch lifecycle states, and inspect active connections on your native MySQL database. +--- + +Every native MySQL database ships with programmatic health checks, and the engine's own instrumentation is fully available to you. There is nothing to install in the database for these checks. + +# Database health {% #status %} + +Poll the database status for live health information after the database is ready: uptime, connection counts, replica state, and storage volumes. Use it from your own monitoring: + +{% multicode %} +```server-nodejs +import { Client, Mysql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +const status = await mysql.getStatus({ + databaseId: '<DATABASE_ID>', +}); +``` +```server-deno +import { Client, Mysql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +const status = await mysql.getStatus({ + databaseId: '<DATABASE_ID>', +}); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Mysql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$mysql = new Mysql($client); + +$status = $mysql->getStatus( + databaseId: '<DATABASE_ID>', +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.mysql import Mysql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +mysql = Mysql(client) + +status = mysql.get_status( + database_id='<DATABASE_ID>', +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +mysql = Mysql.new(client) + +status = mysql.get_status( + database_id: '<DATABASE_ID>', +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Mysql mysql = new Mysql(client); + +var status = await mysql.GetStatus( + databaseId: "<DATABASE_ID>" +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Mysql mysql = Mysql(client); + +final status = await mysql.getStatus( + databaseId: '<DATABASE_ID>', +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Mysql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val mysql = Mysql(client) + +val status = mysql.getStatus( + databaseId = "<DATABASE_ID>", +) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let mysql = Mysql(client) + +let status = try await mysql.getStatus( + databaseId: "<DATABASE_ID>" +) +``` +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewMysql(client) + + result, err := service.GetStatus("<DATABASE_ID>") + if err != nil { + panic(err) + } + _ = result +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::mysql::Mysql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let mysql = Mysql::new(&client); + + let status = mysql.get_status("<DATABASE_ID>").await?; + + Ok(()) +} +``` +```bash +curl -X GET \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <YOUR_API_KEY>" \ + https://<REGION>.cloud.appwrite.io/v1/mysql/<DATABASE_ID>/status +``` +{% /multicode %} + +For the database lifecycle state (`ready`, `scaling`, `restoring`, and friends), read the `status` field of the database object itself. Use that field from deploy pipelines to wait for the database; see [lifecycle states](/docs/products/databases/mysql/maintenance#states). + +# Inspect activity in the engine {% #activity %} + +MySQL's own instrumentation works unmodified. From the `mysql` client or any driver: + +```sql +-- live connections and their current statements +SELECT id, user, host, db, command, time, state, info +FROM performance_schema.processlist; + +-- kill a runaway connection +KILL <id>; + +-- execution plan for a slow query +EXPLAIN ANALYZE SELECT ...; +``` + +A healthy OLTP database keeps its working set in memory. If throughput drops while disk reads climb, move up a [specification](/docs/products/databases/mysql/scaling) so the buffer pool fits the working set. diff --git a/src/routes/docs/products/databases/mysql/network-security/+page.markdoc b/src/routes/docs/products/databases/mysql/network-security/+page.markdoc new file mode 100644 index 00000000000..576abc37c4d --- /dev/null +++ b/src/routes/docs/products/databases/mysql/network-security/+page.markdoc @@ -0,0 +1,500 @@ +--- +layout: article +title: Network security +description: TLS by default, IP allowlists, and idle timeouts for your MySQL database. +--- + +Every native database is reachable through a unique public hostname, secured with TLS, and protected by network controls that you configure per database. + +# Hostname {% #hostname %} + +Each database gets a stable hostname in the form: + +``` +db-<hash>.<region>.appwrite.center +``` + +The hostname does not change for the lifetime of the database, across restarts, resizes, failovers, and version upgrades. You can copy it from the database response. + +# TLS {% #tls %} + +Connections on Appwrite Cloud are encrypted with TLS, terminated at Appwrite's edge and forwarded to your database over the internal network. Use TLS when connecting to the public hostname. If your driver does not infer TLS from the connection string, configure it to require TLS. + +# IP allowlist {% #ip-allowlist %} + +By default, any host that has your credentials can reach the database over the public internet. To restrict access to known networks, configure an IP allowlist. Connections from addresses outside the allowlist are dropped at the network layer, before authentication. + +From the API, pass CIDR blocks or single addresses: + +{% multicode %} + +```server-nodejs +import { Client, Mysql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +await mysql.update({ + databaseId: '<DATABASE_ID>', + networkIPAllowlist: ['203.0.113.0/24', '198.51.100.7'], +}); +``` + +```server-deno +import { Client, Mysql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +await mysql.update({ + databaseId: '<DATABASE_ID>', + networkIPAllowlist: ['203.0.113.0/24', '198.51.100.7'], +}); +``` + +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Mysql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$mysql = new Mysql($client); + +$mysql->update( + databaseId: '<DATABASE_ID>', + networkIPAllowlist: ['203.0.113.0/24', '198.51.100.7'], +); +``` + +```server-python +from appwrite.client import Client +from appwrite.services.mysql import Mysql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +mysql = Mysql(client) + +mysql.update( + database_id='<DATABASE_ID>', + network_i_p_allowlist=['203.0.113.0/24', '198.51.100.7'], +) +``` + +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +mysql = Mysql.new(client) + +mysql.update( + database_id: '<DATABASE_ID>', + network_i_p_allowlist: ['203.0.113.0/24', '198.51.100.7'], +) +``` + +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Mysql mysql = new Mysql(client); + +await mysql.Update( + databaseId: "<DATABASE_ID>", + networkIPAllowlist: new List<string> { "203.0.113.0/24", "198.51.100.7" } +); +``` + +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Mysql mysql = Mysql(client); + +await mysql.update( + databaseId: '<DATABASE_ID>', + networkIPAllowlist: ['203.0.113.0/24', '198.51.100.7'], +); +``` + +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Mysql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val mysql = Mysql(client) + +mysql.update( + databaseId = "<DATABASE_ID>", + networkIPAllowlist = listOf("203.0.113.0/24", "198.51.100.7"), +) +``` + +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let mysql = Mysql(client) + +_ = try await mysql.update( + databaseId: "<DATABASE_ID>", + networkIPAllowlist: ["203.0.113.0/24", "198.51.100.7"] +) +``` + +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" + "github.com/appwrite/sdk-for-go/mysql" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewMysql(client) + + _, err := service.Update( + "<DATABASE_ID>", + mysql.WithUpdateNetworkIPAllowlist([]string{"203.0.113.0/24", "198.51.100.7"}), + ) + if err != nil { + panic(err) + } +} +``` + +```server-rust +use appwrite::Client; +use appwrite::services::Mysql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let mysql = Mysql::new(&client); + + mysql.update( + "<DATABASE_ID>", + None, + None, + None, + None, + None, + None, + Some(vec!["203.0.113.0/24".to_string(), "198.51.100.7".to_string()]), + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + None, + ).await?; + + Ok(()) +} +``` + +```bash +curl -X PATCH \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <API_KEY>" \ + -H "Content-Type: application/json" \ + -d '{ + "networkIPAllowlist": [ + "203.0.113.0/24", + "198.51.100.7" + ] + }' \ + https://<REGION>.cloud.appwrite.io/v1/mysql/<DATABASE_ID> +``` + +{% /multicode %} + +Rules: + +- Entries are IPv4 or IPv6 addresses or CIDR blocks, up to 100 entries per database. +- An empty allowlist means the database accepts connections from any address. +- The allowlist applies to the database and pooler ports. Appwrite's internal infrastructure, backups, monitoring, and replication are unaffected. + +{% info title="Don't lock yourself out" %} +If you connect from networks with changing addresses (home ISPs, mobile networks, serverless platforms without static egress), an allowlist can block you. Add your serverless provider's egress ranges, or leave the allowlist empty and rely on strong credentials and rotation. +{% /info %} + +# Idle timeout {% #idle-timeout %} + +Connections that stay idle are closed by the edge proxy after `networkIdleTimeoutSeconds`, 900 seconds by default. Long-lived driver pools usually send periodic keepalives and are not affected. Raise the timeout if you hold connections open across long pauses; lower it to reclaim connection slots faster. + +{% multicode %} + +```server-nodejs +import { Client, Mysql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +await mysql.update({ + databaseId: '<DATABASE_ID>', + networkIdleTimeoutSeconds: 900, +}); +``` + +```server-deno +import { Client, Mysql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +await mysql.update({ + databaseId: '<DATABASE_ID>', + networkIdleTimeoutSeconds: 900, +}); +``` + +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Mysql; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$mysql = new Mysql($client); + +$mysql->update( + databaseId: '<DATABASE_ID>', + networkIdleTimeoutSeconds: 900, +); +``` + +```server-python +from appwrite.client import Client +from appwrite.services.mysql import Mysql + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +mysql = Mysql(client) + +mysql.update( + database_id='<DATABASE_ID>', + network_idle_timeout_seconds=900, +) +``` + +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +mysql = Mysql.new(client) + +mysql.update( + database_id: '<DATABASE_ID>', + network_idle_timeout_seconds: 900, +) +``` + +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Mysql mysql = new Mysql(client); + +await mysql.Update( + databaseId: "<DATABASE_ID>", + networkIdleTimeoutSeconds: 900 +); +``` + +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Mysql mysql = Mysql(client); + +await mysql.update( + databaseId: '<DATABASE_ID>', + networkIdleTimeoutSeconds: 900, +); +``` + +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Mysql + +val client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val mysql = Mysql(client) + +mysql.update( + databaseId = "<DATABASE_ID>", + networkIdleTimeoutSeconds = 900, +) +``` + +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let mysql = Mysql(client) + +_ = try await mysql.update( + databaseId: "<DATABASE_ID>", + networkIdleTimeoutSeconds: 900 +) +``` + +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" + "github.com/appwrite/sdk-for-go/mysql" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewMysql(client) + + _, err := service.Update( + "<DATABASE_ID>", + mysql.WithUpdateNetworkIdleTimeoutSeconds(900), + ) + if err != nil { + panic(err) + } +} +``` + +```server-rust +use appwrite::Client; +use appwrite::services::Mysql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://<REGION>.cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let mysql = Mysql::new(&client); + + mysql.update("<DATABASE_ID>", None, None, None, None, None, Some(900), None, None, None, None, None, None, None, None, None, None, None, None, None, None).await?; + + Ok(()) +} +``` + +```bash +curl -X PATCH \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <API_KEY>" \ + -H "Content-Type: application/json" \ + -d '{ + "networkIdleTimeoutSeconds": 900 + }' \ + https://<REGION>.cloud.appwrite.io/v1/mysql/<DATABASE_ID> +``` + +{% /multicode %} + +# Locking down access {% #checklist %} + +For a production database: + +1. Set an IP allowlist covering only your application's egress addresses. +2. Rotate the [primary password](/docs/products/databases/mysql/connections#rotate) on a schedule, and after anyone with access leaves your team. +3. Watch [connection activity](/docs/products/databases/mysql/monitoring#activity) for unexpected clients. diff --git a/src/routes/docs/products/databases/mysql/quick-start/+page.markdoc b/src/routes/docs/products/databases/mysql/quick-start/+page.markdoc new file mode 100644 index 00000000000..ffac64735be --- /dev/null +++ b/src/routes/docs/products/databases/mysql/quick-start/+page.markdoc @@ -0,0 +1,104 @@ +--- +layout: article +title: Quick start +description: Create your first native MySQL database in the Appwrite Console, retrieve its credentials, and run your first queries with the mysql client. +--- + +You can create a MySQL database and run your first query in a few minutes. + +# Create a database {% #create %} + +1. In your project, go to **Databases**. +2. Click **Create database**. +3. Give your database a name, and optionally a custom database ID. +4. Under **Choose database type**, select **MySQL** from the **Native databases** group. + +{% only_dark %} +![Create database type selection](/images/docs/products/databases/mysql/dark/create-database-type.avif) +{% /only_dark %} +{% only_light %} +![Create database type selection](/images/docs/products/databases/mysql/create-database-type.avif) +{% /only_light %} + +5. Under **Specifications**, select your preferred tier. +6. Optionally configure **Read replicas** and **Point-in-time recovery (PITR)**. You can change both later. + +{% only_dark %} +![Database specifications](/images/docs/products/databases/mysql/dark/create-database-specs.avif) +{% /only_dark %} +{% only_light %} +![Database specifications](/images/docs/products/databases/mysql/create-database-specs.avif) +{% /only_light %} + +7. Review the database summary and click **Create database**. + +Your database starts provisioning and becomes `ready` shortly after. + +# Get your connection details {% #credentials %} + +The connection details are returned on the database object. Fetch the database with an API key that has the `databases.read` scope: + +```server-nodejs +import { Client, Mysql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +const database = await mysql.get({ + databaseId: '<DATABASE_ID>', +}); + +console.log(database.connectionString); +``` + +The response includes the hostname, port, username, password, and the generated database name, plus a ready-made connection string in the form `mysql://admin:<password>@db-<hash>.<region>.appwrite.center:3306/<database>`. See [Connections](/docs/products/databases/mysql/connections) for the full response and every language. + +# Connect with the mysql client {% #mysql-client %} + +Pass the connection details to the `mysql` command-line client: + +```bash +mysql -h db-<hash>.<region>.appwrite.center -P 3306 -u admin -p -D <database> +``` + +Enter the password when prompted. + +# Run your first queries {% #first-queries %} + +Create a table, insert a row, and read it back: + +```sql +CREATE TABLE books ( + id BIGINT AUTO_INCREMENT PRIMARY KEY, + title TEXT NOT NULL, + author TEXT NOT NULL +); + +INSERT INTO books (title, author) +VALUES ('The Hitchhiker''s Guide to the Galaxy', 'Douglas Adams'); + +SELECT * FROM books; +``` + +You can run the same queries from your application with any MySQL driver. See [Connections](/docs/products/databases/mysql/connections) for driver examples. + +# Next steps {% #next-steps %} + +{% cards %} +{% cards_item href="/docs/products/databases/mysql/connections" title="Connections" %} +Connect from your application with any MySQL driver or ORM. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/backups" title="Backups" %} +Configure backup policies and point-in-time recovery. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/high-availability" title="High availability" %} +Add read replicas with automatic failover. +{% /cards_item %} +{% cards_item href="/docs/products/databases/mysql/monitoring" title="Monitoring" %} +Poll live health and status information from your pipelines. +{% /cards_item %} +{% /cards %} diff --git a/src/routes/docs/products/databases/mysql/scaling/+page.markdoc b/src/routes/docs/products/databases/mysql/scaling/+page.markdoc new file mode 100644 index 00000000000..5506e47060e --- /dev/null +++ b/src/routes/docs/products/databases/mysql/scaling/+page.markdoc @@ -0,0 +1,649 @@ +--- +layout: article +title: Scaling +description: Resize the compute specification of your MySQL database with zero downtime and grow storage automatically as your data grows. +--- + +Native databases scale in two dimensions: the compute specification (CPU, memory, and connection limit) and storage. Both can change after creation, without dump-and-restore migrations. + +# List available specifications {% #specifications %} + +Each database runs against a specification that defines its CPU, memory, included storage, and maximum connections. List the specifications available to your plan: + +{% multicode %} +```server-nodejs +import { Client, Mysql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +const specifications = await mysql.listSpecifications({ + +}); +``` +```server-deno +import { Client, Mysql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +const specifications = await mysql.listSpecifications({ + +}); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Mysql; + +$client = (new Client()) + ->setEndpoint('https://cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$mysql = new Mysql($client); + +$specifications = $mysql->listSpecifications( + +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.mysql import Mysql + +client = Client() +client.set_endpoint('https://cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +mysql = Mysql(client) + +specifications = mysql.list_specifications( + +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +mysql = Mysql.new(client) + +specifications = mysql.list_specifications( + +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Mysql mysql = new Mysql(client); + +var specifications = await mysql.ListSpecifications( + +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Mysql mysql = Mysql(client); + +final specifications = await mysql.listSpecifications( + +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Mysql + +val client = Client() + .setEndpoint("https://cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val mysql = Mysql(client) + +val specifications = mysql.listSpecifications( + +) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let mysql = Mysql(client) + +let specifications = try await mysql.listSpecifications( + +) +``` +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewMysql(client) + + result, err := service.ListSpecifications() + if err != nil { + panic(err) + } + _ = result +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::mysql::Mysql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let mysql = Mysql::new(&client); + + let specifications = mysql.list_specifications().await?; + + Ok(()) +} +``` +```bash +curl -X GET \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <YOUR_API_KEY>" \ + https://cloud.appwrite.io/v1/mysql/specifications +``` +{% /multicode %} + +# Change the compute specification {% #resize %} + +From the API, pass the new specification ID: + +{% multicode %} +```server-nodejs +import { Client, Mysql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +await mysql.update({ + databaseId: '<DATABASE_ID>', + specification: '<SPECIFICATION>', +}); +``` +```server-deno +import { Client, Mysql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +await mysql.update({ + databaseId: '<DATABASE_ID>', + specification: '<SPECIFICATION>', +}); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Mysql; + +$client = (new Client()) + ->setEndpoint('https://cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$mysql = new Mysql($client); + +$mysql->update( + databaseId: '<DATABASE_ID>', + specification: '<SPECIFICATION>', +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.mysql import Mysql + +client = Client() +client.set_endpoint('https://cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +mysql = Mysql(client) + +mysql.update( + database_id='<DATABASE_ID>', + specification='<SPECIFICATION>', +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +mysql = Mysql.new(client) + +mysql.update( + database_id: '<DATABASE_ID>', + specification: '<SPECIFICATION>', +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Mysql mysql = new Mysql(client); + +await mysql.Update( + databaseId: "<DATABASE_ID>", + specification: "<SPECIFICATION>" +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Mysql mysql = Mysql(client); + +await mysql.update( + databaseId: '<DATABASE_ID>', + specification: '<SPECIFICATION>', +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Mysql + +val client = Client() + .setEndpoint("https://cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val mysql = Mysql(client) + +mysql.update( + databaseId = "<DATABASE_ID>", + specification = "<SPECIFICATION>", +) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let mysql = Mysql(client) + +_ = try await mysql.update( + databaseId: "<DATABASE_ID>", + specification: "<SPECIFICATION>" +) +``` +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" + "github.com/appwrite/sdk-for-go/mysql" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewMysql(client) + + _, err := service.Update( + "<DATABASE_ID>", + mysql.WithUpdateSpecification("<SPECIFICATION>"), + ) + if err != nil { + panic(err) + } +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::mysql::Mysql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let mysql = Mysql::new(&client); + + mysql.update("<DATABASE_ID>", None, None, Some("<SPECIFICATION>"), None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None).await?; + + Ok(()) +} +``` +```bash +curl -X PATCH \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <YOUR_API_KEY>" \ + -H "Content-Type: application/json" \ + -d '{ + "specification": "<SPECIFICATION>" + }' \ + https://cloud.appwrite.io/v1/mysql/<DATABASE_ID> +``` +{% /multicode %} + +Resizes apply with zero downtime through a rolling cutover: a new instance is provisioned on the target specification, data is streamed over, and traffic cuts over once it has caught up. The database status shows `scaling` while the resize is in progress. + +# Storage {% #storage %} + +Each specification includes a storage allowance, and storage beyond the allowance is billed per GB. Storage only grows; you cannot shrink a database's storage after it has expanded. To reclaim a smaller footprint, restore a [backup](/docs/products/databases/mysql/backups) into a new database. + +# Storage autoscaling {% #autoscaling %} + +With storage autoscaling enabled, Appwrite grows the storage automatically when usage crosses a threshold, so the database never hits a full disk. Configure it through the API: + +{% multicode %} +```server-nodejs +import { Client, Mysql } from 'node-appwrite'; + +const client = new Client() + .setEndpoint('https://cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +await mysql.update({ + databaseId: '<DATABASE_ID>', + storageAutoscaling: true, + storageAutoscalingThresholdPercent: 85, + storageAutoscalingMaxGb: 500, +}); +``` +```server-deno +import { Client, Mysql } from "npm:node-appwrite"; + +const client = new Client() + .setEndpoint('https://cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +const mysql = new Mysql(client); + +await mysql.update({ + databaseId: '<DATABASE_ID>', + storageAutoscaling: true, + storageAutoscalingThresholdPercent: 85, + storageAutoscalingMaxGb: 500, +}); +``` +```server-php +<?php + +use Appwrite\Client; +use Appwrite\Services\Mysql; + +$client = (new Client()) + ->setEndpoint('https://cloud.appwrite.io/v1') + ->setProject('<PROJECT_ID>') + ->setKey('<YOUR_API_KEY>'); + +$mysql = new Mysql($client); + +$mysql->update( + databaseId: '<DATABASE_ID>', + storageAutoscaling: true, + storageAutoscalingThresholdPercent: 85, + storageAutoscalingMaxGb: 500, +); +``` +```server-python +from appwrite.client import Client +from appwrite.services.mysql import Mysql + +client = Client() +client.set_endpoint('https://cloud.appwrite.io/v1') +client.set_project('<PROJECT_ID>') +client.set_key('<YOUR_API_KEY>') + +mysql = Mysql(client) + +mysql.update( + database_id='<DATABASE_ID>', + storage_autoscaling=True, + storage_autoscaling_threshold_percent=85, + storage_autoscaling_max_gb=500, +) +``` +```server-ruby +require 'appwrite' + +include Appwrite + +client = Client.new + .set_endpoint('https://cloud.appwrite.io/v1') + .set_project('<PROJECT_ID>') + .set_key('<YOUR_API_KEY>') + +mysql = Mysql.new(client) + +mysql.update( + database_id: '<DATABASE_ID>', + storage_autoscaling: true, + storage_autoscaling_threshold_percent: 85, + storage_autoscaling_max_gb: 500, +) +``` +```server-dotnet +using Appwrite; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://cloud.appwrite.io/v1") + .SetProject("<PROJECT_ID>") + .SetKey("<YOUR_API_KEY>"); + +Mysql mysql = new Mysql(client); + +await mysql.Update( + databaseId: "<DATABASE_ID>", + storageAutoscaling: true, + storageAutoscalingThresholdPercent: 85, + storageAutoscalingMaxGb: 500 +); +``` +```server-dart +import 'package:dart_appwrite/dart_appwrite.dart'; + +Client client = Client() + .setEndpoint('https://cloud.appwrite.io/v1') + .setProject('<PROJECT_ID>') + .setKey('<YOUR_API_KEY>'); + +Mysql mysql = Mysql(client); + +await mysql.update( + databaseId: '<DATABASE_ID>', + storageAutoscaling: true, + storageAutoscalingThresholdPercent: 85, + storageAutoscalingMaxGb: 500, +); +``` +```server-kotlin +import io.appwrite.Client +import io.appwrite.services.Mysql + +val client = Client() + .setEndpoint("https://cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +val mysql = Mysql(client) + +mysql.update( + databaseId = "<DATABASE_ID>", + storageAutoscaling = true, + storageAutoscalingThresholdPercent = 85, + storageAutoscalingMaxGb = 500, +) +``` +```server-swift +import Appwrite + +let client = Client() + .setEndpoint("https://cloud.appwrite.io/v1") + .setProject("<PROJECT_ID>") + .setKey("<YOUR_API_KEY>") + +let mysql = Mysql(client) + +_ = try await mysql.update( + databaseId: "<DATABASE_ID>", + storageAutoscaling: true, + storageAutoscalingThresholdPercent: 85, + storageAutoscalingMaxGb: 500 +) +``` +```server-go +package main + +import ( + "github.com/appwrite/sdk-for-go/appwrite" + "github.com/appwrite/sdk-for-go/mysql" +) + +func main() { + client := appwrite.NewClient( + appwrite.WithEndpoint("https://cloud.appwrite.io/v1"), + appwrite.WithProject("<PROJECT_ID>"), + appwrite.WithKey("<YOUR_API_KEY>"), + ) + + service := appwrite.NewMysql(client) + + _, err := service.Update( + "<DATABASE_ID>", + mysql.WithUpdateStorageAutoscaling(true), + mysql.WithUpdateStorageAutoscalingThresholdPercent(85), + mysql.WithUpdateStorageAutoscalingMaxGb(500), + ) + if err != nil { + panic(err) + } +} +``` +```server-rust +use appwrite::client::Client; +use appwrite::services::mysql::Mysql; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new() + .set_endpoint("https://cloud.appwrite.io/v1") + .set_project("<PROJECT_ID>") + .set_key("<YOUR_API_KEY>"); + + let mysql = Mysql::new(&client); + + mysql.update("<DATABASE_ID>", None, None, None, None, None, None, None, None, None, None, Some(true), Some(85), Some(500), None, None, None, None, None, None, None).await?; + + Ok(()) +} +``` +```bash +curl -X PATCH \ + -H "X-Appwrite-Project: <PROJECT_ID>" \ + -H "X-Appwrite-Key: <YOUR_API_KEY>" \ + -H "Content-Type: application/json" \ + -d '{ + "storageAutoscaling": true, + "storageAutoscalingThresholdPercent": 85, + "storageAutoscalingMaxGb": 500 + }' \ + https://cloud.appwrite.io/v1/mysql/<DATABASE_ID> +``` +{% /multicode %} + +| Parameter | Range | Description | +|---------------------------------------|--------------------|-----------------------------------------------------------| +| `storageAutoscaling` | boolean | Enable automatic storage growth | +| `storageAutoscalingThresholdPercent` | 50 - 95 | Usage percentage that triggers an expansion (default 85) | +| `storageAutoscalingMaxGb` | integer, 0 = no cap | Upper bound for automatic growth | + +Set a cap if you want a hard ceiling on storage cost; without one, autoscaling grows storage as needed and the overage is billed per GB. + +# Picking a specification {% #picking %} + +Guidelines for choosing a starting tier: + +- **Connections**: count the maximum concurrent connections your application opens, including all replicas of your app server. If it exceeds the specification's connection cap, either move up a tier or put the [connection pooler](/docs/products/databases/mysql/connection-pooling) in front. +- **Memory**: MySQL performs best when the working set fits in memory. Track cache hit ratio with database metrics; a sustained ratio below ~99% for an OLTP workload is a sign to add memory. +- **CPU**: sustained CPU above 70-80% at normal load leaves no headroom for spikes, migrations, or backups. + +Start small and resize up when the metrics say so; resizes are online, so there is no penalty for growing later. diff --git a/static/images/docs/products/databases/mysql/create-database-specs.avif b/static/images/docs/products/databases/mysql/create-database-specs.avif new file mode 100644 index 0000000000000000000000000000000000000000..fac1583d4dc3541bd01f46a2e8a787e89bc6c0cc GIT binary patch literal 32210 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 literal 0 HcmV?d00001 diff --git a/static/images/docs/products/databases/mysql/create-database-type.avif b/static/images/docs/products/databases/mysql/create-database-type.avif new file mode 100644 index 0000000000000000000000000000000000000000..0f4763f6ad640513a97e1f4de63e3d369bb28c60 GIT binary patch literal 38356 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 W6D)=X*nAR2$*9SW|LY3@_4g^jpk~GZ literal 0 HcmV?d00001 diff --git a/static/images/docs/products/databases/mysql/dark/create-database-specs.avif b/static/images/docs/products/databases/mysql/dark/create-database-specs.avif new file mode 100644 index 0000000000000000000000000000000000000000..2349dd1482f4f8131d822d3002d7c4d98c2f560f GIT binary patch literal 34014 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∾c=wNjTK@MI?2#IA`GIn^mi9=z&uUBpH=+i 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 literal 0 HcmV?d00001 diff --git a/static/images/docs/products/databases/mysql/dark/create-database-type.avif b/static/images/docs/products/databases/mysql/dark/create-database-type.avif new file mode 100644 index 0000000000000000000000000000000000000000..4c1257ed5620d2127f37627370043abc7d2f3be0 GIT binary patch literal 41317 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�+5dX<$m`kZY7i|10er67-vI~+hAu^bLkPG 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 Ez#0VUYXATM literal 0 HcmV?d00001 From 02bc531d1b851e19062839e772148ad3e5838fbc Mon Sep 17 00:00:00 2001 From: Atharva Deosthale <atharva.deosthale17@gmail.com> Date: Thu, 9 Jul 2026 01:28:49 +0530 Subject: [PATCH 8/8] Add draft announcement posts for DocumentsDB, VectorsDB, and native databases --- .../post/announcing-documentsdb/+page.markdoc | 328 ++++++++++++++ .../+page.markdoc | 80 ++++ .../+page.markdoc | 88 ++++ .../post/announcing-vectorsdb/+page.markdoc | 418 ++++++++++++++++++ 4 files changed, 914 insertions(+) create mode 100644 src/routes/blog/post/announcing-documentsdb/+page.markdoc create mode 100644 src/routes/blog/post/announcing-native-mysql-databases/+page.markdoc create mode 100644 src/routes/blog/post/announcing-native-postgresql-databases/+page.markdoc create mode 100644 src/routes/blog/post/announcing-vectorsdb/+page.markdoc diff --git a/src/routes/blog/post/announcing-documentsdb/+page.markdoc b/src/routes/blog/post/announcing-documentsdb/+page.markdoc new file mode 100644 index 00000000000..08d51ba866f --- /dev/null +++ b/src/routes/blog/post/announcing-documentsdb/+page.markdoc @@ -0,0 +1,328 @@ +--- +layout: post +title: "Announcing DocumentsDB: Documents that evolve with your product" +description: Store flexible JSON documents, query them with the Appwrite SDKs, and let your data model evolve with your product instead of ahead of it. +date: 2026-07-09 +cover: /images/blog/announcing-documentsdb/cover.png +timeToRead: 5 +author: atharva +category: announcement +featured: false +callToAction: true +draft: true +faqs: + - question: "What is Appwrite DocumentsDB?" + answer: "DocumentsDB is an Appwrite database for schemaless documents. Collections hold flexible JSON, so you can add or change fields as your application grows without defining columns or running schema migrations. You work with it through the Appwrite SDKs and APIs, with the same permissions, queries, and pagination used across Appwrite Databases." + - question: "How is DocumentsDB different from TablesDB?" + answer: "TablesDB is relational: you define typed columns and indexes up front, and every row follows that schema. DocumentsDB is schemaless: every document is JSON and its shape can vary between documents in the same collection. Choose TablesDB when your data is structured and consistent, and DocumentsDB when it changes shape often or arrives in unpredictable forms." + - question: "Does DocumentsDB support transactions and bulk operations?" + answer: "Yes. DocumentsDB shares the platform capabilities used across Appwrite Databases, including transactions, bulk operations, atomic numeric operations for counters, pagination, and ordering. Permissions work at the document level, so client applications can read and write data safely." + - question: "Can I import existing data into DocumentsDB?" + answer: "Yes, DocumentsDB supports JSON imports and exports. You can bring existing documents in from a JSON file and export collections back out, which makes migrations into and out of Appwrite straightforward." + - question: "How is a DocumentsDB database provisioned?" + answer: "You create a database, choose DocumentsDB as the type, and select a compute specification that fits your workload. From there you can back it up and scale it as usage grows, all from the same project as the rest of your Appwrite backend." + - question: "Is DocumentsDB available on Appwrite Cloud?" + answer: "Yes, DocumentsDB is available on Appwrite Cloud as a database type in the create database flow, with a compute specification you choose per database." +--- + +Most application data does not arrive with a fixed shape. Early products change weekly, integrations return payloads you do not control, and user-generated content rarely fits the columns you designed three months ago. Forcing all of that through a rigid schema turns every product change into a migration. + +That is why we are announcing **DocumentsDB**, an Appwrite database built for schemaless documents. + +# Create your first database + +In your project, go to **Databases**, click **Create database**, and choose **DocumentsDB** as the type. Pick a compute specification, and the database is ready to hold collections in minutes. + +![Creating a DocumentsDB database](/images/docs/databases/documentsdb/dark/create-database.avif) + +# Schemaless collections + +A DocumentsDB collection holds documents as JSON. There are no columns to define and no schema to migrate. Two documents in the same collection can have different fields, and adding a new field is as simple as writing it. + +You still get the full capabilities of an Appwrite database: document-level permissions, queries, ordering, and pagination, through the same SDK patterns as the rest of Appwrite Databases. + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const documentsDB = new sdk.DocumentsDB(client); + +const result = await documentsDB.createDocument({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: sdk.ID.unique(), + data: { title: 'Hamlet', year: 1601 }, + permissions: [sdk.Permission.read(sdk.Role.any())] // optional +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const documentsDB = new sdk.DocumentsDB(client); + +const result = await documentsDB.createDocument({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: sdk.ID.unique(), + data: { title: 'Hamlet', year: 1601 }, + permissions: [sdk.Permission.read(sdk.Role.any())] // optional +}); +``` +```php +<?php + +use Appwrite\Client; +use Appwrite\Services\DocumentsDB; +use Appwrite\ID; +use Appwrite\Permission; +use Appwrite\Role; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('<YOUR_PROJECT_ID>') // Your project ID + ->setKey('<YOUR_API_KEY>'); // Your secret API key + +$documentsDB = new DocumentsDB($client); + +$result = $documentsDB->createDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: ID::unique(), + data: ['title' => 'Hamlet', 'year' => 1601], + permissions: [Permission::read(Role::any())] // optional +); +``` +```python +from appwrite.client import Client +from appwrite.services.documents_db import DocumentsDB +from appwrite.id import ID +from appwrite.permission import Permission +from appwrite.role import Role + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('<YOUR_PROJECT_ID>') # Your project ID +client.set_key('<YOUR_API_KEY>') # Your secret API key + +documents_db = DocumentsDB(client) + +result = documents_db.create_document( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>', + document_id = ID.unique(), + data = { "title": "Hamlet", "year": 1601 }, + permissions = [Permission.read(Role.any())] # optional +) +``` +```ruby +require 'appwrite' + +include Appwrite +include Appwrite::Permission +include Appwrite::Role + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('<YOUR_PROJECT_ID>') # Your project ID + .set_key('<YOUR_API_KEY>') # Your secret API key + +documents_db = DocumentsDB.new(client) + +result = documents_db.create_document( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + document_id: ID.unique(), + data: { "title" => "Hamlet", "year" => 1601 }, + permissions: [Permission.read(Role.any())] # optional +) +``` +```csharp +using Appwrite; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("<YOUR_PROJECT_ID>") // Your project ID + .SetKey("<YOUR_API_KEY>"); // Your secret API key + +DocumentsDB documentsDB = new DocumentsDB(client); + +Document result = await documentsDB.CreateDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: ID.Unique(), + data: new { title = "Hamlet", year = 1601 }, + permissions: new List<string> { Permission.Read(Role.Any()) } // optional +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; +import 'package:dart_appwrite/permission.dart'; +import 'package:dart_appwrite/role.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +DocumentsDB documentsDB = DocumentsDB(client); + +Document result = await documentsDB.createDocument( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + documentId: ID.unique(), + data: { "title": "Hamlet", "year": 1601 }, + permissions: [Permission.read(Role.any())], // (optional) +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.ID +import io.appwrite.Permission +import io.appwrite.Role +import io.appwrite.services.DocumentsDB + +val client = Client(context) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +val documentsDB = DocumentsDB(client) + +val response = documentsDB.createDocument( + databaseId = "<DATABASE_ID>", + collectionId = "<COLLECTION_ID>", + documentId = ID.unique(), + data = mapOf("title" to "Hamlet", "year" to 1601), + permissions = listOf(Permission.read(Role.any())), // optional +) +``` +```java +import io.appwrite.Client; +import io.appwrite.ID; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.DocumentsDB; +import java.util.Map; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>"); // Your secret API key + +DocumentsDB documentsDB = new DocumentsDB(client); + +documentsDB.createDocument( + "<DATABASE_ID>", + "<COLLECTION_ID>", + ID.unique(), + Map.of("title", "Hamlet", "year", 1601), + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +let documentsDB = DocumentsDB(client) + +let document = try await documentsDB.createDocument( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + documentId: ID.unique(), + data: ["title": "Hamlet", "year": 1601], + permissions: [Permission.read(Role.any())] // optional +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::DocumentsDB; +use appwrite::id::ID; +use appwrite::permission::Permission; +use appwrite::role::Role; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let documents_db = DocumentsDB::new(&client); + + let result = documents_db.create_document( + "<DATABASE_ID>", + "<COLLECTION_ID>", + ID::unique(), + serde_json::json!({ "title": "Hamlet", "year": 1601 }), + Some(vec![Permission::read(Role::any()).to_string()]), // optional + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite documents-db create-document \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --document-id 'unique()' \ + --data '{ "title": "Hamlet", "year": 1601 }' +``` +{% /multicode %} + +# Platform capabilities included + +DocumentsDB is a first-class member of Appwrite Databases, so the capabilities that make application data manageable come built in: + +- **[Transactions](/docs/products/databases/documentsdb/transactions)** group writes so related changes succeed or fail together. +- **[Bulk operations](/docs/products/databases/documentsdb/bulk-operations)** create, update, or delete many documents in one request. +- **[Atomic numeric operations](/docs/products/databases/documentsdb/atomic-numeric-operations)** increment and decrement counters safely on the server, with no read-modify-write races. +- **[JSON imports](/docs/products/databases/documentsdb/json-imports) and [exports](/docs/products/databases/documentsdb/json-exports)** move existing data in and out without custom scripts. +- **[Backups](/docs/products/databases/documentsdb/backups)** protect your data with scheduled and manual snapshots. + +Because permissions are enforced at the document level, you can serve data directly to client applications without building an API layer in between. + +# Compute specifications + +When you create a DocumentsDB database, you select a compute specification that fits your workload, and the database is provisioned for your project with its own resources. As usage grows, backups and scaling are handled from the same place you manage the rest of your Appwrite project. + +# When to use DocumentsDB + +DocumentsDB fits workloads where the shape of the data is the moving part: + +- Product catalogs where every category carries different attributes +- Event and activity payloads from third-party integrations +- User-generated content with optional and evolving fields +- Prototypes that need persistence before the data model settles + +If your data is structured and consistent, [TablesDB](/docs/products/databases/tablesdb) with its typed columns and indexes remains the right choice. The two share the same platform, so mixing them within one project is normal. + +# Get started + +DocumentsDB is available on Appwrite Cloud today. Create a database, choose DocumentsDB as the type, and you can write your first document within minutes. + +- [DocumentsDB documentation](/docs/products/databases/documentsdb) +- [Quick start](/docs/products/databases/documentsdb/quick-start) + diff --git a/src/routes/blog/post/announcing-native-mysql-databases/+page.markdoc b/src/routes/blog/post/announcing-native-mysql-databases/+page.markdoc new file mode 100644 index 00000000000..c1063ae58b5 --- /dev/null +++ b/src/routes/blog/post/announcing-native-mysql-databases/+page.markdoc @@ -0,0 +1,80 @@ +--- +layout: post +title: "Announcing native MySQL databases: Bring your MySQL workloads to Appwrite" +description: Provision a managed MySQL 8.4 instance inside your Appwrite project and keep using the drivers, ORMs, and tools your applications already depend on. +date: 2026-07-09 +cover: /images/blog/announcing-native-mysql-databases/cover.png +timeToRead: 5 +author: atharva +category: announcement +featured: false +callToAction: true +draft: true +faqs: + - question: "What is a native MySQL database in Appwrite?" + answer: "It is a managed MySQL instance running on dedicated compute inside your Appwrite project. Appwrite provisions the engine with its own hostname, credentials, and TLS, and you connect with the mysql client or any MySQL driver. Appwrite manages the infrastructure; your code talks to MySQL directly." + - question: "Do the Appwrite SDKs manage data in a native MySQL database?" + answer: "No. Native databases are accessed with standard MySQL clients, drivers, and ORMs, not the Appwrite SDKs. If you want SDK-driven data APIs with built-in permissions, use an Appwrite database such as TablesDB, DocumentsDB, or VectorsDB instead." + - question: "Which MySQL versions are available?" + answer: "MySQL 8.4 is the default, with 8.0 also supported. Version upgrades run online with logical replication and a traffic cutover, so moving between supported versions does not require a dump and restore." + - question: "Can I move an existing MySQL application to Appwrite?" + answer: "Yes, that is the primary use case. Because the database is a standard MySQL engine, existing applications built on frameworks like Laravel, Django, Rails, or Spring Boot connect with a changed connection string and no code rewrite." + - question: "What infrastructure features are included?" + answer: "Scheduled backups and point-in-time recovery based on binary log archiving, database branches, high availability with up to five replicas and automatic failover, online compute resizing, storage autoscaling, IP allowlists, a ProxySQL-based connection pooler, and maintenance windows." + - question: "How is the MySQL offering different from the PostgreSQL one?" + answer: "The platform features are the same: identical compute specifications and pricing, backups, PITR, branches, high availability, scaling, and network controls. The engine-specific difference is extensions, which are a PostgreSQL concept and do not apply to MySQL." +--- + +MySQL runs an enormous share of the software already in production. Most teams considering a backend platform are not starting from zero; they have a Laravel application, a Django service, or a decade-old schema that works, and the real question is where it should live. + +Today we are announcing **native MySQL databases** in Appwrite, so the answer can be: inside the same project as the rest of your backend. + +# Create your first database + +Provisioning happens in the Console: + +1. In your project, go to **Databases** and click **Create database**. +2. Under **Choose database type**, select **MySQL** from the **Native databases** group. + +![Choosing MySQL in the create database flow](/images/docs/products/databases/mysql/dark/create-database-type.avif) + +3. Under **Specifications**, pick the tier that fits your workload, and optionally configure read replicas and point-in-time recovery. + +![Selecting a specification](/images/docs/products/databases/mysql/dark/create-database-specs.avif) + +4. Review the summary and click **Create database**. + +The database provisions in minutes and reports `ready` when you can connect. + +# Connect your existing application + +A native MySQL database is a standard MySQL 8.4 engine (8.0 is also supported) with its own hostname, credentials, and TLS. Connecting is exactly what you expect: + +```bash +mysql -h db-<hash>.<region>.appwrite.center -P 3306 -u admin -p -D <database> +``` + +Change the connection string in your existing application and it runs. We verified the common paths end to end and published [integration guides](/docs/products/databases/mysql/integrations/laravel) for Laravel, Django, Rails, Spring Boot, EF Core, GORM, Prisma, Drizzle, and more, each with the MySQL-specific configuration spelled out. + +Because this is the engine itself, the Appwrite SDKs are not part of the data path. Reads and writes go through your drivers and ORMs, the way they already do. If you want SDK-driven data APIs with document permissions instead, that is what [Appwrite Databases](/docs/products/databases) are for. Native databases and Appwrite databases live side by side in the same project, so you can use both. + +# Managed operations + +Provisioning MySQL is straightforward; operating it over time is where the cost accumulates. The managed layer covers that operational work: + +- **[Backups and PITR.](/docs/products/databases/mysql/backups)** Scheduled and manual backups, plus continuous binary log archiving that restores to any point in the retention window, such as the second before a bad migration. +- **[High availability.](/docs/products/databases/mysql/high-availability)** Up to five replicas with a choice of replication mode and automatic failover behind a stable hostname. +- **[Branches.](/docs/products/databases/mysql/branches)** Instant, isolated copies of the database for previews and CI, created from a storage snapshot. +- **[Scaling.](/docs/products/databases/mysql/scaling)** Online resizes across eight compute tiers and storage autoscaling with a configurable threshold. +- **[Connection pooling.](/docs/products/databases/mysql/connection-pooling)** A ProxySQL-based pooler absorbs connection churn from serverless and per-request runtimes. +- **[Network security.](/docs/products/databases/mysql/network-security)** TLS on by default and IP allowlists enforced before authentication. + +Compute specifications and pricing are identical to the PostgreSQL offering, starting at **$10 per month**, with the full table in the [documentation](/docs/products/databases/mysql#specifications). + +# Get started + +Native MySQL databases are available on Appwrite Cloud today on dedicated infrastructure. + +- [MySQL documentation](/docs/products/databases/mysql) +- [Quick start](/docs/products/databases/mysql/quick-start) + diff --git a/src/routes/blog/post/announcing-native-postgresql-databases/+page.markdoc b/src/routes/blog/post/announcing-native-postgresql-databases/+page.markdoc new file mode 100644 index 00000000000..815ec150e4f --- /dev/null +++ b/src/routes/blog/post/announcing-native-postgresql-databases/+page.markdoc @@ -0,0 +1,88 @@ +--- +layout: post +title: "Announcing native PostgreSQL databases: The full engine, provisioned in minutes" +description: Run a managed PostgreSQL instance inside your Appwrite project and connect to it with psql, your ORM, and the entire PostgreSQL ecosystem. +date: 2026-07-09 +cover: /images/blog/announcing-native-postgresql-databases/cover.png +timeToRead: 6 +author: atharva +category: announcement +featured: false +callToAction: true +draft: true +faqs: + - question: "What is a native PostgreSQL database in Appwrite?" + answer: "It is a managed PostgreSQL instance provisioned on dedicated compute for your Appwrite project. You get the raw engine with its own hostname, credentials, and TLS, and you connect with psql or any PostgreSQL driver. There is no Appwrite abstraction layer between your code and the database." + - question: "How is a native database different from Appwrite Databases like TablesDB?" + answer: "Appwrite databases such as TablesDB, DocumentsDB, and VectorsDB are accessed through Appwrite SDKs and platform APIs, with document permissions and platform features built in. A native PostgreSQL database is the engine itself: you bring your own ORM, migrations, and drivers, and Appwrite manages the infrastructure underneath." + - question: "Can I use the Appwrite SDK to read and write data in a native PostgreSQL database?" + answer: "No. Data in a native database is accessed with standard PostgreSQL clients, drivers, and ORMs rather than the Appwrite SDKs. That is the point of the product: your existing PostgreSQL code and tooling work unchanged." + - question: "Which PostgreSQL versions are supported?" + answer: "PostgreSQL 18 is the default, with 17 also supported. Version upgrades run online: a second instance is provisioned on the new version, data streams over with logical replication, and traffic cuts over without a read or write outage." + - question: "What infrastructure features are included?" + answer: "Scheduled backups and point-in-time recovery, database branches, high availability with up to five replicas, online compute resizing, storage autoscaling, IP allowlists, a connection pooler, and maintenance windows. Extensions like PostGIS and pgvector can be installed per database." + - question: "How much does a native PostgreSQL database cost?" + answer: "Compute specifications start at $10 per month for 1 vCPU and 1 GB of memory and scale up to 8 vCPU and 64 GB. Storage and bandwidth allowances are included per tier, with overages and optional add-ons like high availability replicas and point-in-time recovery billed on top." +--- + +Some projects outgrow abstractions. You want `psql`, your own migrations, an ORM you chose yourself, and the thirty years of tooling that surround PostgreSQL, without also taking on provisioning, backups, failover, and patching. + +Today we are announcing **native PostgreSQL databases** in Appwrite. You pick a compute specification, Appwrite provisions the engine in your project's region, and you connect to it like any PostgreSQL server, because it is one. + +# Create your first database + +Provisioning happens in the Console: + +1. In your project, go to **Databases** and click **Create database**. +2. Under **Choose database type**, select **PostgreSQL** from the **Native databases** group. + +![Choosing PostgreSQL in the create database flow](/images/docs/products/databases/postgresql/dark/create-database-type.avif) + +3. Under **Specifications**, pick the tier that fits your workload, and optionally configure read replicas and point-in-time recovery. + +![Selecting a specification](/images/docs/products/databases/postgresql/dark/create-database-specs.avif) + +4. Review the summary and click **Create database**. + +The database provisions in minutes and reports `ready` when you can connect. + +# Direct access to the PostgreSQL engine + +A native database gets its own hostname, credentials, and TLS out of the box: + +```bash +psql "postgresql://admin:<password>@db-<hash>.<region>.appwrite.center:5432/<database>" +``` + +From there, everything you know applies. Prisma, Drizzle, Django, Rails, Spring Boot, EF Core, and GORM work against it with no Appwrite-specific configuration, and we ship [integration guides](/docs/products/databases/postgresql/integrations/prisma) for each. Extensions like PostGIS, pgvector, and pg_trgm install per database. + +This is a different product from [Appwrite Databases](/docs/products/databases). TablesDB, DocumentsDB, and VectorsDB are accessed through Appwrite SDKs with platform permissions built in. A native PostgreSQL database has no Appwrite layer between your code and the engine, and the Appwrite SDKs do not manage its data. Your drivers do. + +# Managed infrastructure features + +Appwrite manages the operational work that self-hosting PostgreSQL would put on your team: + +- **[Backups and point-in-time recovery.](/docs/products/databases/postgresql/backups)** Scheduled and manual backups, plus continuous archiving that can restore to any moment inside the retention window. +- **[Branches.](/docs/products/databases/postgresql/branches)** Ephemeral copies of your database created from a storage snapshot, ideal for previews and testing against production-shaped data. +- **[High availability.](/docs/products/databases/postgresql/high-availability)** Up to five replicas with asynchronous, synchronous, or quorum replication and automatic failover behind a stable hostname. +- **[Scaling.](/docs/products/databases/postgresql/scaling)** Resize compute online between eight specifications, and let storage autoscaling grow the disk before it fills. +- **[Connection pooling.](/docs/products/databases/postgresql/connection-pooling)** A per-database pooler multiplexes serverless traffic, with read/write splitting when replicas are enabled. +- **[Network security.](/docs/products/databases/postgresql/network-security)** TLS by default, IP allowlists, and a dedicated hostname per database. + +# SQL tooling in the Console + +The Console treats the database as a first-class SQL environment. The SQL editor runs queries with formatting and explain plans, the Monitor tab tracks compute, connections, storage, and workload, and the active connections view surfaces what `pg_stat_activity` knows with actions to cancel or terminate sessions. + +![The SQL editor in the Appwrite Console](/images/docs/products/databases/postgresql/dark/sql-editor.avif) + +# Specifications and pricing + +Specifications run from **$10 per month** (1 vCPU, 1 GB memory, 10 GB storage) to **$699 per month** (8 vCPU, 64 GB memory, 3 TB storage), each with included storage and bandwidth. High availability replicas and point-in-time recovery are add-ons, priced as a percentage of the tier. The full table lives in the [documentation](/docs/products/databases/postgresql#specifications). + +# Get started + +Native PostgreSQL databases are available on Appwrite Cloud today on dedicated infrastructure. + +- [PostgreSQL documentation](/docs/products/databases/postgresql) +- [Quick start](/docs/products/databases/postgresql/quick-start) + diff --git a/src/routes/blog/post/announcing-vectorsdb/+page.markdoc b/src/routes/blog/post/announcing-vectorsdb/+page.markdoc new file mode 100644 index 00000000000..89867d70e9e --- /dev/null +++ b/src/routes/blog/post/announcing-vectorsdb/+page.markdoc @@ -0,0 +1,418 @@ +--- +layout: post +title: "Announcing VectorsDB: Similarity search as a first-class Appwrite database" +description: Store embeddings, generate them from text with built-in models, and rank documents by similarity without adding a separate vector service to your stack. +date: 2026-07-09 +cover: /images/blog/announcing-vectorsdb/cover.png +timeToRead: 6 +author: atharva +category: announcement +featured: false +callToAction: true +draft: true +faqs: + - question: "What is Appwrite VectorsDB?" + answer: "VectorsDB is an Appwrite database for vector embeddings and similarity search. Every collection is created with a fixed dimension, documents hold an embeddings vector plus optional JSON metadata, and an HNSW index keeps similarity search fast as the collection grows." + - question: "Do I need a separate embedding service to use VectorsDB?" + answer: "No. VectorsDB can generate text embeddings with built-in models, so you can turn strings into vectors and store them in one flow. If you already produce embeddings elsewhere, you can store those instead, as long as their length matches the collection's dimension." + - question: "Which similarity metrics does VectorsDB support?" + answer: "VectorsDB supports cosine, dot product, and Euclidean distance. You choose the metric when you create the HNSW index, and query with the matching vector query method to get documents ranked from most to least similar." + - question: "What is an HNSW index and why does it matter?" + answer: "HNSW (Hierarchical Navigable Small World) is an approximate nearest neighbor index. It keeps similarity search fast even as collections grow large, which is what makes vector search practical in production instead of a linear scan over every document." + - question: "Can I combine vector search with regular queries?" + answer: "Yes. A vector query can be combined with other queries, such as limits, so you can cap how many results come back. Results return as documents with their metadata, ready to render or feed into your application logic." + - question: "What can I build with VectorsDB?" + answer: "Semantic search over content, recommendations based on similarity, deduplication, and retrieval for AI applications such as RAG. Anywhere ranking by meaning beats matching by exact value, VectorsDB applies." +--- + +Semantic search, recommendations, and retrieval for AI features all reduce to the same primitive: store vectors, then find the ones closest to a query. Until now, that primitive usually meant adding a dedicated vector service to your stack, with its own hosting, its own client, and its own auth model to reconcile with the rest of your backend. + +Today we are announcing **VectorsDB**, which makes that primitive a first-class Appwrite database. + +# Create your first database + +In your project, go to **Databases**, click **Create database**, and choose **VectorsDB** as the type. Pick a compute specification, then create your first collection with the `dimension` your embedding model produces. From there, every document you write is a vector ready to be searched. + +# A schema designed for vectors + +Where other Appwrite databases let you define your own fields, a VectorsDB collection has a deliberate, fixed shape. You create it with a `dimension`, and every document carries two things: + +- `embeddings`: a vector of exactly that length +- `metadata`: optional JSON for whatever belongs alongside the vector, such as the source text, a URL, or labels + +That constraint is the feature. The collection always knows what a valid vector looks like, and the HNSW index built on `embeddings` keeps search fast as your data grows. + +# Built-in embedding generation + +VectorsDB can generate text embeddings with built-in models. You pass a string, and Appwrite turns it into a vector you can store directly, so a working semantic search does not require standing up an embedding service or wiring a third-party API into your ingest path. If you already have embeddings from your own models, store those instead. + +# Run a similarity search + +Searching is a two-step flow. First, turn the search text into a vector, either with your own model or with the built-in embedding generation: + +{% multicode %} +```server-nodejs +const sdk = require('node-appwrite'); + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.createTextEmbeddings({ + texts: ['The quick brown fox jumps over the lazy dog'], + model: sdk.EmbeddingModel.Nomicembedtext // optional, defaults to nomic-embed-text +}); +``` +```deno +import * as sdk from "npm:node-appwrite"; + +const client = new sdk.Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +const vectorsDB = new sdk.VectorsDB(client); + +const result = await vectorsDB.createTextEmbeddings({ + texts: ['The quick brown fox jumps over the lazy dog'], + model: sdk.EmbeddingModel.Nomicembedtext // optional, defaults to nomic-embed-text +}); +``` +```php +<?php + +use Appwrite\Client; +use Appwrite\Services\VectorsDB; +use Appwrite\Enums\EmbeddingModel; + +$client = (new Client()) + ->setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + ->setProject('<YOUR_PROJECT_ID>') // Your project ID + ->setKey('<YOUR_API_KEY>'); // Your secret API key + +$vectorsDB = new VectorsDB($client); + +$result = $vectorsDB->createTextEmbeddings( + texts: ['The quick brown fox jumps over the lazy dog'], + model: EmbeddingModel::NOMICEMBEDTEXT() // optional, defaults to nomic-embed-text +); +``` +```python +from appwrite.client import Client +from appwrite.services.vectors_db import VectorsDB +from appwrite.enums import EmbeddingModel + +client = Client() +client.set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint +client.set_project('<YOUR_PROJECT_ID>') # Your project ID +client.set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB(client) + +result = vectors_db.create_text_embeddings( + texts = ['The quick brown fox jumps over the lazy dog'], + model = EmbeddingModel.NOMIC_EMBED_TEXT # optional, defaults to nomic-embed-text +) +``` +```ruby +require 'appwrite' + +include Appwrite +include Appwrite::Enums + +client = Client.new + .set_endpoint('https://<REGION>.cloud.appwrite.io/v1') # Your API Endpoint + .set_project('<YOUR_PROJECT_ID>') # Your project ID + .set_key('<YOUR_API_KEY>') # Your secret API key + +vectors_db = VectorsDB.new(client) + +result = vectors_db.create_text_embeddings( + texts: ['The quick brown fox jumps over the lazy dog'], + model: EmbeddingModel::NOMIC_EMBED_TEXT # optional, defaults to nomic-embed-text +) +``` +```csharp +using Appwrite; +using Appwrite.Enums; +using Appwrite.Models; +using Appwrite.Services; + +Client client = new Client() + .SetEndPoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .SetProject("<YOUR_PROJECT_ID>") // Your project ID + .SetKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +EmbeddingList result = await vectorsDB.CreateTextEmbeddings( + texts: new List<string> { "The quick brown fox jumps over the lazy dog" }, + model: EmbeddingModel.NomicEmbedText // optional, defaults to nomic-embed-text +); +``` +```dart +import 'package:dart_appwrite/dart_appwrite.dart'; +import 'package:dart_appwrite/enums.dart'; + +Client client = Client() + .setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint + .setProject('<YOUR_PROJECT_ID>') // Your project ID + .setKey('<YOUR_API_KEY>'); // Your secret API key + +VectorsDB vectorsDB = VectorsDB(client); + +EmbeddingList result = await vectorsDB.createTextEmbeddings( + texts: ['The quick brown fox jumps over the lazy dog'], + model: EmbeddingModel.nomicEmbedText, // optional, defaults to nomic-embed-text +); +``` +```kotlin +import io.appwrite.Client +import io.appwrite.enums.EmbeddingModel +import io.appwrite.services.VectorsDB + +val client = Client(context) + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +val vectorsDB = VectorsDB(client) + +val response = vectorsDB.createTextEmbeddings( + texts = listOf("The quick brown fox jumps over the lazy dog"), + model = EmbeddingModel.NOMIC_EMBED_TEXT, // optional, defaults to nomic-embed-text +) +``` +```java +import io.appwrite.Client; +import io.appwrite.enums.EmbeddingModel; +import io.appwrite.coroutines.CoroutineCallback; +import io.appwrite.services.VectorsDB; +import java.util.List; + +Client client = new Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>"); // Your secret API key + +VectorsDB vectorsDB = new VectorsDB(client); + +vectorsDB.createTextEmbeddings( + List.of("The quick brown fox jumps over the lazy dog"), + EmbeddingModel.NOMIC_EMBED_TEXT, // optional, defaults to nomic-embed-text + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +import Appwrite +import AppwriteEnums + +let client = Client() + .setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint + .setProject("<YOUR_PROJECT_ID>") // Your project ID + .setKey("<YOUR_API_KEY>") // Your secret API key + +let vectorsDB = VectorsDB(client) + +let embeddingList = try await vectorsDB.createTextEmbeddings( + texts: ["The quick brown fox jumps over the lazy dog"], + model: .nomicEmbedText // optional, defaults to nomic-embed-text +) +``` +```server-rust +use appwrite::Client; +use appwrite::services::vectors_db::VectorsDB; +use appwrite::enums::EmbeddingModel; + +#[tokio::main] +async fn main() -> Result<(), Box<dyn std::error::Error>> { + let client = Client::new(); + client.set_endpoint("https://<REGION>.cloud.appwrite.io/v1"); // Your API Endpoint + client.set_project("<YOUR_PROJECT_ID>"); // Your project ID + client.set_key("<YOUR_API_KEY>"); // Your secret API key + + let vectors_db = VectorsDB::new(&client); + + let result = vectors_db.create_text_embeddings( + vec!["The quick brown fox jumps over the lazy dog"], + Some(EmbeddingModel::NomicEmbedText), // optional, defaults to nomic-embed-text + ).await?; + + println!("{:?}", result); + Ok(()) +} +``` +```bash +appwrite vectors-db create-text-embeddings \ + --texts 'The quick brown fox jumps over the lazy dog' \ + --model 'nomic-embed-text' +``` +{% /multicode %} + +Then pass that vector as a query to the same `listDocuments` method used across Appwrite Databases. Choose the metric when you create the index, cosine, dot product, or Euclidean distance, and query with the matching method. The vectors below are shortened for readability; in practice you pass the embedding returned by the step above: + +{% multicode %} +```server-nodejs +const result = await vectorsDB.listDocuments({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + sdk.Query.vectorCosine('embeddings', [0.11, 0.21, 0.30, 0.40]), + sdk.Query.limit(3) + ] +}); +``` +```deno +const result = await vectorsDB.listDocuments({ + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + sdk.Query.vectorCosine('embeddings', [0.11, 0.21, 0.30, 0.40]), + sdk.Query.limit(3) + ] +}); +``` +```php +$result = $vectorsDB->listDocuments( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + Query::vectorCosine('embeddings', [0.11, 0.21, 0.30, 0.40]), + Query::limit(3) + ] +); +``` +```python +result = vectors_db.list_documents( + database_id = '<DATABASE_ID>', + collection_id = '<COLLECTION_ID>', + queries = [ + Query.vector_cosine('embeddings', [0.11, 0.21, 0.30, 0.40]), + Query.limit(3) + ] +) +``` +```ruby +result = vectors_db.list_documents( + database_id: '<DATABASE_ID>', + collection_id: '<COLLECTION_ID>', + queries: [ + Query.vector_cosine('embeddings', [0.11, 0.21, 0.30, 0.40]), + Query.limit(3) + ] +) +``` +```csharp +DocumentList result = await vectorsDB.ListDocuments( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + queries: new List<string> { + Query.VectorCosine("embeddings", new List<object> { 0.11, 0.21, 0.30, 0.40 }), + Query.Limit(3) + } +); +``` +```dart +DocumentList result = await vectorsDB.listDocuments( + databaseId: '<DATABASE_ID>', + collectionId: '<COLLECTION_ID>', + queries: [ + Query.vectorCosine('embeddings', [0.11, 0.21, 0.30, 0.40]), + Query.limit(3) + ], +); +``` +```kotlin +val result = vectorsDB.listDocuments( + databaseId = "<DATABASE_ID>", + collectionId = "<COLLECTION_ID>", + queries = listOf( + Query.vectorCosine("embeddings", listOf(0.11, 0.21, 0.30, 0.40)), + Query.limit(3) + ), +) +``` +```java +vectorsDB.listDocuments( + "<DATABASE_ID>", + "<COLLECTION_ID>", + List.of( + Query.vectorCosine("embeddings", List.of(0.11, 0.21, 0.30, 0.40)), + Query.limit(3) + ), + new CoroutineCallback<>((result, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + System.out.println(result); + }) +); +``` +```swift +let result = try await vectorsDB.listDocuments( + databaseId: "<DATABASE_ID>", + collectionId: "<COLLECTION_ID>", + queries: [ + Query.vectorCosine("embeddings", [0.11, 0.21, 0.30, 0.40]), + Query.limit(3) + ] +) +``` +```server-rust +let result = vectors_db.list_documents( + "<DATABASE_ID>", + "<COLLECTION_ID>", + Some(vec![ + Query::vector_cosine("embeddings", json!([0.11, 0.21, 0.30, 0.40])).to_string(), + Query::limit(3).to_string(), + ]), + None, // transaction_id + None, // total + None, // ttl +).await?; +``` +```bash +appwrite vectors-db list-documents \ + --database-id <DATABASE_ID> \ + --collection-id <COLLECTION_ID> \ + --queries '{"method":"vectorCosine","attribute":"embeddings","values":[[0.11,0.21,0.30,0.40]]}' '{"method":"limit","values":[3]}' +``` +{% /multicode %} + +Results come back as documents ranked from most to least similar, with their metadata attached, ready to render. + +# Shared Appwrite Databases capabilities + +VectorsDB shares the platform capabilities available across Appwrite Databases: + +- **[Permissions](/docs/products/databases/vectorsdb/permissions)** control access at the document level, so clients can search safely. +- **[Queries](/docs/products/databases/vectorsdb/queries)**, **[pagination](/docs/products/databases/vectorsdb/pagination)**, and ordering work alongside vector queries. +- **[Transactions](/docs/products/databases/vectorsdb/transactions)** group writes so related changes succeed or fail together. +- **[Bulk operations](/docs/products/databases/vectorsdb/bulk-operations)** ingest large embedding sets in one request. +- **[CSV imports](/docs/products/databases/vectorsdb/csv-imports) and [exports](/docs/products/databases/vectorsdb/csv-exports)** move vectors and metadata in and out. +- **[Backups](/docs/products/databases/vectorsdb/backups)** protect your collections with scheduled and manual snapshots. + +Your vectors live next to the rest of your application data, behind the same SDKs and the same access control, instead of in a service on the side. + +Every VectorsDB database is provisioned for your project with a compute specification you choose at creation, so search performance scales with the tier you pick. + +# Get started + +VectorsDB is available on Appwrite Cloud today. Create a database, choose VectorsDB as the type, pick a dimension, and you can run your first similarity search in minutes. + +- [VectorsDB documentation](/docs/products/databases/vectorsdb) +- [Quick start](/docs/products/databases/vectorsdb/quick-start) +- [Vector search](/docs/products/databases/vectorsdb/vector-search) +