Skip to content

Round-trip vectorsdb collection dimension through migrations#210

Merged
abnegate merged 1 commit into
mainfrom
feat/vectorsdb-collection-dimension
Jul 22, 2026
Merged

Round-trip vectorsdb collection dimension through migrations#210
abnegate merged 1 commit into
mainfrom
feat/vectorsdb-collection-dimension

Conversation

@abnegate

Copy link
Copy Markdown
Member

What

  • Resources\Database\Collection carries a nullable dimension (fromArray + jsonSerialize), and the Appwrite source exports it when listing tables, so archive entity lines preserve it.
  • Destinations\Appwrite accepts an optional collectionStructures constructor map keyed by database type. When the imported database's type has an entry, createDatabase builds the per-database metadata collection from that structure instead of the generic one, and createEntity writes the type-specific metadata (vectorsdb dimension).
  • Archives written before dimension was serialized carry none, so createEntity writes a schema-satisfying placeholder and syncVectorDimension corrects it from the vector column's size when the embeddings field is imported.
  • DocumentsDB/VectorsDB::fromArray no longer warn when the nested database object lacks the database DSN key (older archive lines).

Why

Restoring a vectorsdb backup produced a working database whose collection reported dimension: null, and creating additional collections on it failed structure validation: the vectorsdb metadata schema requires dimension but the destination created the metadata collection from the generic databases schema and never wrote the value. Companion to appwrite-labs/cloud#4908.

Existing callers are unaffected: without a collectionStructures entry, behavior is unchanged.

Tests

tests/Migration/Unit/Resources/CollectionTest.php covers the dimension round trip (fromArray → jsonSerialize → fromArray) and the null default. Full unit suite green, Pint and PHPStan (level 3) clean. End-to-end coverage lands in cloud's testVectorsDBBackupAndRestore.

🤖 Generated with Claude Code

A restored vectorsdb collection lost its dimension: the Collection
resource never carried it, so archives dropped it at write time, and
the destination both created the per-database metadata collection from
the generic databases schema (which lacks the attribute) and wrote
collection documents without it. Restored collections reported
dimension null and creating additional collections on a restored
vectorsdb database failed structure validation.

Collection now carries a nullable dimension (serialized and exported
from the Appwrite source), and the destination accepts an optional
collectionStructures map keyed by database type so vectorsdb databases
get their own metadata schema. Types with an entry get dimension
written on entity import; archives written before dimension was
serialized get a placeholder that syncVectorDimension corrects from
the vector column size when the embeddings field is imported.

DocumentsDB/VectorsDB fromArray also stop warning on entity lines
whose nested database object predates the database DSN key.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 22, 2026 03:50

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@greptile-apps

greptile-apps Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR preserves vectorsdb collection dimensions during Appwrite migrations. The main changes are:

  • Adds nullable dimension support to collection resources.
  • Exports Appwrite table dimensions into collection resource data.
  • Lets Appwrite destinations use type-specific collection metadata schemas.
  • Backfills vectorsdb collection dimension from imported vector attributes.
  • Allows older DocumentsDB and VectorsDB archive payloads without a database DSN.

Confidence Score: 4/5

The vectorsdb restore path can persist the wrong collection dimension when multiple vector attributes are imported.

  • The type-specific metadata setup is consistent with the new resource shape.
  • Dimension backfill is too broad and can use the wrong vector attribute size.
  • The new serialization shape may affect strict archive consumers because null dimensions are now emitted.

src/Migration/Destinations/Appwrite.php, src/Migration/Resources/Database/Collection.php

Important Files Changed

Filename Overview
src/Migration/Destinations/Appwrite.php Adds type-specific metadata collection structures and vectorsdb dimension writes, with a bug where any vector attribute can overwrite the collection dimension.
src/Migration/Resources/Database/Collection.php Adds nullable dimension parsing and serialization, but serializes the null field for every collection.
src/Migration/Sources/Appwrite.php Adds dimension to exported table resource data, defaulting to null when the source table has no field.
src/Migration/Resources/Database/DocumentsDB.php Defaults a missing nested database DSN to an empty string for older archive payloads.
src/Migration/Resources/Database/VectorsDB.php Defaults a missing nested database DSN to an empty string for older archive payloads.
tests/Migration/Unit/Resources/CollectionTest.php Adds tests for collection dimension round-tripping and null defaults.

Fix All in Claude Code Fix All in Codex

Prompt To Fix All With AI
Fix the following 2 code review issues. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 2
src/Migration/Destinations/Appwrite.php:1332
**Vector Dimension Overwritten**

When a vectorsdb collection has more than one vector attribute, this sync runs for each one and writes the collection-level `dimension` from the current attribute size. A later non-`embeddings` vector field with a different size can overwrite the restored collection metadata, so new inserts or collection operations validate against the wrong dimension.

### Issue 2 of 2
src/Migration/Resources/Database/Collection.php:76
**Null Dimension Changes Archives**

`Collection::jsonSerialize()` now writes `dimension: null` for every collection that does not set a dimension, including non-vectors collections and older archive data. Any strict archive reader or downstream schema that only accepts the previous collection shape can reject otherwise valid non-vectors collection exports because the field is present instead of omitted.

Reviews (1): Last reviewed commit: "feat: round-trip vectorsdb collection di..." | Re-trigger Greptile

{
if (
$type !== UtopiaDatabase::VAR_VECTOR
|| $resource->getTable()->getDatabase()->getType() !== Resource::TYPE_DATABASE_VECTORSDB

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Vector Dimension Overwritten

When a vectorsdb collection has more than one vector attribute, this sync runs for each one and writes the collection-level dimension from the current attribute size. A later non-embeddings vector field with a different size can overwrite the restored collection metadata, so new inserts or collection operations validate against the wrong dimension.

Knowledge Base Used:

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/Migration/Destinations/Appwrite.php
Line: 1332

Comment:
**Vector Dimension Overwritten**

When a vectorsdb collection has more than one vector attribute, this sync runs for each one and writes the collection-level `dimension` from the current attribute size. A later non-`embeddings` vector field with a different size can overwrite the restored collection metadata, so new inserts or collection operations validate against the wrong dimension.

**Knowledge Base Used:**
- [Destinations](https://app.greptile.com/appwrite/-/custom-context/knowledge-base/utopia-php/migration/-/docs/destinations.md)
- [Resource Model Classes](https://app.greptile.com/appwrite/-/custom-context/knowledge-base/utopia-php/migration/-/docs/resources.md)

How can I resolve this? If you propose a fix, please make it concise.

Fix in Claude Code Fix in Codex

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed: syncVectorDimension now only writes when the collection's dimension is still the placeholder (0), so it fills in the value for pre-dimension archives but never overwrites an archived dimension — a second vector column import is a no-op.

public function jsonSerialize(): array
{
return array_merge(parent::jsonSerialize(), [
'dimension' => $this->dimension,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Null Dimension Changes Archives

Collection::jsonSerialize() now writes dimension: null for every collection that does not set a dimension, including non-vectors collections and older archive data. Any strict archive reader or downstream schema that only accepts the previous collection shape can reject otherwise valid non-vectors collection exports because the field is present instead of omitted.

Knowledge Base Used:

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/Migration/Resources/Database/Collection.php
Line: 76

Comment:
**Null Dimension Changes Archives**

`Collection::jsonSerialize()` now writes `dimension: null` for every collection that does not set a dimension, including non-vectors collections and older archive data. Any strict archive reader or downstream schema that only accepts the previous collection shape can reject otherwise valid non-vectors collection exports because the field is present instead of omitted.

**Knowledge Base Used:**
- [Resource Model Classes](https://app.greptile.com/appwrite/-/custom-context/knowledge-base/utopia-php/migration/-/docs/resources.md)
- [Migration Sources](https://app.greptile.com/appwrite/-/custom-context/knowledge-base/utopia-php/migration/-/docs/sources.md)

How can I resolve this? If you propose a fix, please make it concise.

Fix in Claude Code Fix in Codex

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed: jsonSerialize now omits dimension when unset, so documentsdb and other non-vector collection lines keep their previous shape.

@abnegate
abnegate merged commit 661015e into main Jul 22, 2026
4 checks passed
@abnegate
abnegate deleted the feat/vectorsdb-collection-dimension branch July 22, 2026 03:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants