initial commit
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
# Adding Fields to an Existing PocketBase Collection
|
||||
|
||||
PocketBase silently drops fields not in the collection schema — no HTTP error, no warning, just data loss. If your app writes fields that PocketBase ignores, you need to add them to the schema.
|
||||
|
||||
## Detection
|
||||
|
||||
Signs that PocketBase is dropping fields:
|
||||
- Code writes a field (e.g., `recommendation`, `explanation`) via `addDoc()` or `updateDoc()`
|
||||
- The record is created/updated with HTTP 200
|
||||
- But re-reading the record shows the field as `undefined`/missing
|
||||
- The field works fine in Firestore but not PocketBase
|
||||
|
||||
## Fix: PATCH the Collection Schema
|
||||
|
||||
Adding fields requires sending the COMPLETE fields array (existing + new) via PATCH:
|
||||
|
||||
```python
|
||||
#!/usr/bin/env python3
|
||||
"""Add fields to existing PocketBase collection"""
|
||||
import json, urllib.request, ssl
|
||||
|
||||
ctx = ssl.create_default_context()
|
||||
ctx.check_hostname = False
|
||||
ctx.verify_mode = ssl.CERT_NONE
|
||||
|
||||
BASE = "http://localhost:8091"
|
||||
COLLECTION_ID = "pbc_863811952" # from GET /api/collections
|
||||
|
||||
# Step 1: Auth as superuser
|
||||
auth_resp = json.loads(urllib.request.urlopen(
|
||||
urllib.request.Request(f"{BASE}/api/collections/_superusers/auth-with-password",
|
||||
data=json.dumps({"identity": "admin@example.com", "password": "..."}).encode(),
|
||||
headers={"Content-Type": "application/json"},
|
||||
method="POST"), context=ctx).read())
|
||||
token = auth_resp["token"]
|
||||
|
||||
# Step 2: Get current fields
|
||||
collections = json.loads(urllib.request.urlopen(
|
||||
urllib.request.Request(f"{BASE}/api/collections",
|
||||
headers={"Authorization": f"Bearer {token}"}), context=ctx).read())
|
||||
svc = next(c for c in collections["items"] if c["id"] == COLLECTION_ID)
|
||||
existing_fields = svc["fields"]
|
||||
|
||||
# Step 3: Build new fields to add
|
||||
new_fields = [
|
||||
{"autogeneratePattern":"","hidden":False,"id":"text_new_1","max":0,"min":0,
|
||||
"name":"explanation","pattern":"","presentable":False,"primaryKey":False,
|
||||
"required":False,"system":False,"type":"text"},
|
||||
{"autogeneratePattern":"","hidden":False,"id":"text_new_2","max":0,"min":0,
|
||||
"name":"recommendation","pattern":"","presentable":False,"primaryKey":False,
|
||||
"required":False,"system":False,"type":"text"},
|
||||
]
|
||||
|
||||
# Step 4: PATCH with complete fields array (existing + new)
|
||||
all_fields = existing_fields + new_fields
|
||||
result = json.loads(urllib.request.urlopen(
|
||||
urllib.request.Request(f"{BASE}/api/collections/{COLLECTION_ID}",
|
||||
data=json.dumps({"fields": all_fields}).encode(),
|
||||
headers={"Authorization": f"Bearer {token}", "Content-Type": "application/json"},
|
||||
method="PATCH"), context=ctx).read())
|
||||
print(f"Updated fields: {[f['name'] for f in result['fields']]}")
|
||||
```
|
||||
|
||||
## Critical Requirements
|
||||
|
||||
1. **Send ALL fields, not just new ones.** PATCH replaces the entire `fields` array. Sending only the new fields will DELETE all existing fields and break the collection.
|
||||
|
||||
2. **Each field needs a unique `id` string.** Use descriptive strings like `text_exp_001` — they just need to be unique within the collection.
|
||||
|
||||
3. **Field types matter.** `text` for strings, `number` for numbers, `bool` for booleans. Use `text` for most fields to be safe.
|
||||
|
||||
4. **No `system:true` for custom fields.** Only the built-in `id` field should have `system:true`.
|
||||
|
||||
## Never Do This
|
||||
|
||||
- **Never edit the SQLite database directly.** Use the REST API. Direct SQLite edits can corrupt field ID tracking and break the collection irreversibly.
|
||||
- **Never use POST to update an existing collection.** POST creates a new collection; PATCH updates an existing one.
|
||||
- **Don't forget to include the `id` field.** The system `id` field must remain in the array.
|
||||
@@ -0,0 +1,48 @@
|
||||
# Adding Fields to PocketBase Collection Schema
|
||||
|
||||
PocketBase silently drops fields not defined in the collection schema — HTTP 200, no error, data just disappears. When you add new fields to the data model, you MUST also add them to the PocketBase schema via API.
|
||||
|
||||
## The problem
|
||||
|
||||
Services saved with `recommendation` and `explanation` fields appeared to save successfully, but the fields were missing when read back. Root cause: the `services` collection schema only had `name`, `price`, `description`, `category`, `duration` — unknown fields were silently stripped on create/update.
|
||||
|
||||
## Detection
|
||||
|
||||
Query the collection schema to see current fields:
|
||||
|
||||
```python
|
||||
# Auth + list collections
|
||||
auth = api("POST", "/api/collections/_superusers/auth-with-password", {
|
||||
"identity": "admin@example.com",
|
||||
"password": "password"
|
||||
})
|
||||
token = auth["token"]
|
||||
cols = api("GET", "/api/collections", token=token)
|
||||
svc = next(c for c in cols["items"] if c["name"] == "services")
|
||||
print([f["name"] for f in svc["fields"]])
|
||||
# ['id', 'userId', 'name', 'description', 'price', 'category', ...]
|
||||
```
|
||||
|
||||
## Fix: PATCH the collection
|
||||
|
||||
Add missing fields by PATCHing the complete fields array (including existing fields):
|
||||
|
||||
```python
|
||||
existing_fields = svc["fields"]
|
||||
new_fields = [
|
||||
{"autogeneratePattern":"","hidden":False,"id":"text_rec_new","max":0,"min":0,
|
||||
"name":"recommendation","pattern":"","presentable":False,"primaryKey":False,
|
||||
"required":False,"system":False,"type":"text"},
|
||||
{"autogeneratePattern":"","hidden":False,"id":"text_exp_new","max":0,"min":0,
|
||||
"name":"explanation","pattern":"","presentable":False,"primaryKey":False,
|
||||
"required":False,"system":False,"type":"text"},
|
||||
]
|
||||
result = api("PATCH", f"/api/collections/{svc['id']}",
|
||||
{"fields": existing_fields + new_fields}, token=token)
|
||||
```
|
||||
|
||||
**Important**: You must send the COMPLETE fields array, not just the new fields. PocketBase replaces the entire schema. Each field needs a unique `id` string — use descriptive names like `text_rec_001` or UUIDs.
|
||||
|
||||
## Full script
|
||||
|
||||
See `scripts/pb_add_fields.py` for a reusable script that auths, lists collections, and adds specified fields.
|
||||
Reference in New Issue
Block a user