initial commit
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Add fields to PocketBase collection schema. PocketBase silently drops fields
|
||||
not in schema — you MUST add them via API when extending the data model.
|
||||
|
||||
Usage: Edit FIELDS_TO_ADD and COLLECTION_NAME below, then run.
|
||||
"""
|
||||
import json, urllib.request, ssl
|
||||
|
||||
# === CONFIG ===
|
||||
PB_URL = "http://localhost:8091"
|
||||
SUPERUSER_EMAIL = "admin@example.com"
|
||||
SUPERUSER_PASSWORD = "password"
|
||||
COLLECTION_NAME = "services" # Change this
|
||||
FIELDS_TO_ADD = [
|
||||
# Example: add a text field
|
||||
{"name": "recommendation", "type": "text"},
|
||||
{"name": "explanation", "type": "text"},
|
||||
# For other field types, see PocketBase API docs
|
||||
# {"name": "duration", "type": "number", "onlyInt": False},
|
||||
]
|
||||
|
||||
ctx = ssl.create_default_context()
|
||||
ctx.check_hostname = False
|
||||
ctx.verify_mode = ssl.CERT_NONE
|
||||
|
||||
def api(method, path, data=None, token=None):
|
||||
headers = {"Content-Type": "application/json"}
|
||||
if token:
|
||||
headers["Authorization"] = f"Bearer {token}"
|
||||
body = json.dumps(data).encode() if data else None
|
||||
req = urllib.request.Request(f"{PB_URL}{path}", data=body, headers=headers, method=method)
|
||||
resp = urllib.request.urlopen(req, context=ctx)
|
||||
return json.loads(resp.read())
|
||||
|
||||
# Step 1: Auth
|
||||
auth_resp = api("POST", "/api/collections/_superusers/auth-with-password", {
|
||||
"identity": SUPERUSER_EMAIL,
|
||||
"password": SUPERUSER_PASSWORD
|
||||
})
|
||||
token = auth_resp["token"]
|
||||
|
||||
# Step 2: Get collection to see current fields
|
||||
collections = api("GET", "/api/collections", token=token)
|
||||
try:
|
||||
col = next(c for c in collections["items"] if c["name"] == COLLECTION_NAME)
|
||||
except StopIteration:
|
||||
print(f"Collection '{COLLECTION_NAME}' not found. Available:",
|
||||
[c["name"] for c in collections["items"]])
|
||||
exit(1)
|
||||
|
||||
print(f"Collection: {col['name']} (id: {col['id']})")
|
||||
print(f"Current fields: {[f['name'] for f in col['fields']]}")
|
||||
|
||||
# Step 3: Build new fields with unique IDs
|
||||
existing_fields = col["fields"]
|
||||
existing_names = {f["name"] for f in existing_fields}
|
||||
new_field_defs = []
|
||||
|
||||
for f in FIELDS_TO_ADD:
|
||||
if f["name"] in existing_names:
|
||||
print(f"Field '{f['name']}' already exists, skipping")
|
||||
continue
|
||||
|
||||
field_type = f.get("type", "text")
|
||||
field_def = {
|
||||
"autogeneratePattern": "",
|
||||
"hidden": False,
|
||||
"id": f"field_{f['name']}_{len(existing_fields) + len(new_field_defs)}",
|
||||
"max": f.get("max", 0),
|
||||
"min": f.get("min", 0),
|
||||
"name": f["name"],
|
||||
"pattern": f.get("pattern", ""),
|
||||
"presentable": False,
|
||||
"primaryKey": False,
|
||||
"required": f.get("required", False),
|
||||
"system": False,
|
||||
"type": field_type,
|
||||
}
|
||||
if field_type == "number":
|
||||
field_def["onlyInt"] = f.get("onlyInt", False)
|
||||
new_field_defs.append(field_def)
|
||||
|
||||
if not new_field_defs:
|
||||
print("No new fields to add.")
|
||||
exit(0)
|
||||
|
||||
# Step 4: PATCH with complete fields array
|
||||
all_fields = existing_fields + new_field_defs
|
||||
result = api("PATCH", f"/api/collections/{col['id']}", {"fields": all_fields}, token=token)
|
||||
print(f"Updated fields: {[f['name'] for f in result['fields']]}")
|
||||
print(f"✅ Added {len(new_field_defs)} field(s) to {COLLECTION_NAME}")
|
||||
Reference in New Issue
Block a user