79 lines
2.6 KiB
Python
79 lines
2.6 KiB
Python
|
|
#!/usr/bin/env python3
|
||
|
|
"""Relax the staged-ingestion number fields that legitimately hold zero.
|
||
|
|
|
||
|
|
PocketBase treats 0 as blank for a ``required`` number field, so
|
||
|
|
``dn_batch_sources.ordinal`` (0 for the first source in a batch) and
|
||
|
|
``dn_batch_pages.region`` (0 for a whole-page read) were rejected on every
|
||
|
|
create. This flips those two fields to optional and touches nothing else.
|
||
|
|
|
||
|
|
Dry run unless ``--apply`` is supplied, and ``--apply`` additionally requires
|
||
|
|
``--confirm-host`` matching the configured PocketBase host exactly.
|
||
|
|
"""
|
||
|
|
import sys
|
||
|
|
|
||
|
|
from pb_env import PB, http, superuser_token
|
||
|
|
|
||
|
|
TARGETS = (("dn_batch_sources", "ordinal"), ("dn_batch_pages", "region"))
|
||
|
|
|
||
|
|
APPLY = "--apply" in sys.argv
|
||
|
|
|
||
|
|
|
||
|
|
def confirmation_host():
|
||
|
|
for index, argument in enumerate(sys.argv):
|
||
|
|
if argument.startswith("--confirm-host="):
|
||
|
|
return argument.split("=", 1)[1]
|
||
|
|
if argument == "--confirm-host" and index + 1 < len(sys.argv):
|
||
|
|
return sys.argv[index + 1]
|
||
|
|
return None
|
||
|
|
|
||
|
|
|
||
|
|
def main():
|
||
|
|
if APPLY and confirmation_host() != PB:
|
||
|
|
sys.exit(
|
||
|
|
f"REFUSING --apply: pass --confirm-host with the exact configured "
|
||
|
|
f"host ({PB})."
|
||
|
|
)
|
||
|
|
|
||
|
|
token = superuser_token()
|
||
|
|
print(f"auth ok on {PB}")
|
||
|
|
print(f"target: {PB} mode: {'APPLY' if APPLY else 'DRY RUN'}")
|
||
|
|
|
||
|
|
changed = 0
|
||
|
|
for collection_name, field_name in TARGETS:
|
||
|
|
code, collection = http("GET", f"/api/collections/{collection_name}", token=token)
|
||
|
|
if code != 200:
|
||
|
|
sys.exit(f"collection {collection_name} not found ({code})")
|
||
|
|
|
||
|
|
fields = collection.get("fields") or collection.get("schema") or []
|
||
|
|
target = next((f for f in fields if f.get("name") == field_name), None)
|
||
|
|
if target is None:
|
||
|
|
sys.exit(f"{collection_name}.{field_name} not found")
|
||
|
|
|
||
|
|
if not target.get("required"):
|
||
|
|
print(f" {collection_name}.{field_name}: already optional")
|
||
|
|
continue
|
||
|
|
|
||
|
|
changed += 1
|
||
|
|
if not APPLY:
|
||
|
|
print(f" {collection_name}.{field_name}: would set required false")
|
||
|
|
continue
|
||
|
|
|
||
|
|
target["required"] = False
|
||
|
|
code, response = http(
|
||
|
|
"PATCH",
|
||
|
|
f"/api/collections/{collection['id']}",
|
||
|
|
{"fields": fields},
|
||
|
|
token=token,
|
||
|
|
)
|
||
|
|
if code != 200:
|
||
|
|
sys.exit(f" {collection_name}.{field_name}: PATCH failed {code}: {response}")
|
||
|
|
print(f" {collection_name}.{field_name}: required -> false")
|
||
|
|
|
||
|
|
if not APPLY:
|
||
|
|
print(f"\nDRY RUN. {changed} field(s) would change. No schema changes written.")
|
||
|
|
else:
|
||
|
|
print(f"\nAPPLIED. {changed} field(s) changed.")
|
||
|
|
|
||
|
|
|
||
|
|
main()
|