File size: 3,159 Bytes
6b1bc4b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | """Generate backend/migrations/012_domains_catalogue.sql for the UniHive `main` repo: seeds the recommender's 13 broad interests and 114 interest tags
into the existing `domains` table. Source of truth: backend/crud/taxonomy.py (recommender branch). Usage: python make_domains_migration.py <taxonomy.py> <out.sql>"""
import importlib.util, sys
src, out = sys.argv[1], sys.argv[2]
spec = importlib.util.spec_from_file_location("taxonomy", src); tx = importlib.util.module_from_spec(spec); spec.loader.exec_module(tx)
q = lambda s: "'" + str(s).replace("'", "''") + "'"
broad, child, names = [], [], set()
for bslug, bname, bdesc, children in tx.TAXONOMY:
bslug = tx.slugify(bname) # phrase slug ('software-development'), not the recommender's short one ('software'): short slugs are ordinary words that main's text matcher would find in everyday posts
assert bname.lower() not in names; names.add(bname.lower()); broad.append((bname, bslug, bdesc))
for c in children:
assert c.lower() not in names, c; names.add(c.lower()); child.append((c, tx.slugify(c), bslug))
assert len(broad) == 13 and len(child) == 114 and len({c[1] for c in child}) == 114 and len({b[1] for b in broad} | {c[1] for c in child}) == 127
allslugs = [s for _, s, _ in broad] + [s for _, s, _ in child]
D = "$$"
sql = f"""-- Migration 012: seed the recommender's interest taxonomy into the existing `domains` table.
-- 13 broad interests (parent_id NULL, phrase slugs such as 'software-development') + 114 interest tags (parent = their broad interest). The tag slugs are the recommender's own
-- (backend/crud/taxonomy.py of the recommender branch), so engine 3.0, the tag suggester (/api/tags/suggest) and the onboarding screen share one set of ids.
-- Additive and safe to run twice: rows that already exist (same slug OR same name) are left untouched, and a NOTICE reports any slug that could not be inserted.
BEGIN;
INSERT INTO domains (name, slug, parent_id, description) VALUES
{(',' + chr(10)).join(f" ({q(n)}, {q(s)}, NULL, {q(d)})" for n, s, d in broad)}
ON CONFLICT DO NOTHING;
INSERT INTO domains (name, slug, parent_id, description)
SELECT v.name, v.slug, p.id, NULL
FROM (VALUES
{(',' + chr(10)).join(f" ({q(n)}, {q(s)}, {q(b)})" for n, s, b in child)}
) AS v(name, slug, parent_slug)
JOIN domains p ON p.slug = v.parent_slug
ON CONFLICT DO NOTHING;
DO {D}
DECLARE missing int;
BEGIN
SELECT count(*) INTO missing FROM (VALUES {", ".join("(" + q(s) + ")" for s in allslugs)}) AS t(slug)
WHERE NOT EXISTS (SELECT 1 FROM domains d WHERE d.slug = t.slug);
IF missing > 0 THEN
RAISE NOTICE '012_domains_catalogue: % taxonomy slugs could not be inserted (a different row already uses the same name or slug): %', missing,
(SELECT string_agg(t.slug, ', ') FROM (VALUES {", ".join("(" + q(s) + ")" for s in allslugs)}) AS t(slug) WHERE NOT EXISTS (SELECT 1 FROM domains d WHERE d.slug = t.slug));
END IF;
END
{D};
COMMIT;
"""
open(out, "w", encoding="utf8", newline="\n").write(sql)
print("written", out, "|", len(broad), "broad +", len(child), "child |", sql.count("\n"), "lines")
|