230 lines
9.4 KiB
Python
230 lines
9.4 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
export_cat_translations.py
|
|
|
|
Exports Polylang category translation data from local DB and generates SQL
|
|
for production. Handles:
|
|
1. wp_terms for translated categories
|
|
2. wp_term_taxonomy (category + language taxonomy rows)
|
|
3. wp_term_taxonomy (term_translations groups)
|
|
4. wp_term_relationships (post→translated category assignments)
|
|
"""
|
|
import pymysql, re
|
|
|
|
DB = dict(host='172.18.0.2', port=3306, user='wordpress_user',
|
|
password='wordpress_pass', database='wordpress_db', charset='utf8mb4',
|
|
cursorclass=pymysql.cursors.DictCursor)
|
|
|
|
# Translated category term_ids on local (ES parent → lang: local_term_id)
|
|
TRANS_CATS = {
|
|
6: {'en': 3077, 'fr': 3083, 'it': 3089, 'pt': 3095},
|
|
21: {'en': 3080, 'fr': 3086, 'it': 3092, 'pt': 3098},
|
|
1646: {'en': 2982, 'fr': 3032, 'it': 3048, 'pt': 3063},
|
|
1647: {'en': 2986, 'fr': 3035, 'it': 3051, 'pt': 3066},
|
|
1648: {'en': 2971, 'fr': 3029, 'it': 3045, 'pt': 3060},
|
|
1650: {'en': 2964, 'fr': 3023, 'it': 3039, 'pt': 3054},
|
|
}
|
|
|
|
# Collect all translated term_ids
|
|
all_trans_ids = []
|
|
for mapping in TRANS_CATS.values():
|
|
all_trans_ids.extend(mapping.values())
|
|
all_trans_ids = sorted(set(all_trans_ids))
|
|
all_es_ids = sorted(TRANS_CATS.keys())
|
|
|
|
db = pymysql.connect(**DB)
|
|
c = db.cursor()
|
|
|
|
sql_lines = [
|
|
"-- Polylang category translations export",
|
|
"-- Generated by export_cat_translations.py",
|
|
"-- Run on production AFTER verifying no term_id conflicts",
|
|
"",
|
|
"SET NAMES utf8mb4;",
|
|
"SET foreign_key_checks = 0;",
|
|
"",
|
|
]
|
|
|
|
# ─── 1. wp_terms ──────────────────────────────────────────────────────────────
|
|
ids_str = ','.join(str(i) for i in all_trans_ids)
|
|
c.execute(f"SELECT term_id, name, slug, term_group FROM wp_terms WHERE term_id IN ({ids_str})")
|
|
rows = c.fetchall()
|
|
sql_lines.append("-- 1. wp_terms (translated category names/slugs)")
|
|
for r in rows:
|
|
name = r['name'].replace("'", "''")
|
|
slug = r['slug'].replace("'", "''")
|
|
sql_lines.append(
|
|
f"INSERT IGNORE INTO wp_terms (term_id, name, slug, term_group) "
|
|
f"VALUES ({r['term_id']}, '{name}', '{slug}', {r['term_group']});"
|
|
)
|
|
sql_lines.append("")
|
|
|
|
# ─── 2. wp_term_taxonomy (category rows for translated terms) ────────────────
|
|
c.execute(f"""
|
|
SELECT term_taxonomy_id, term_id, taxonomy, description, parent, count
|
|
FROM wp_term_taxonomy
|
|
WHERE term_id IN ({ids_str}) AND taxonomy='category'
|
|
""")
|
|
cat_rows = c.fetchall()
|
|
sql_lines.append("-- 2. wp_term_taxonomy (taxonomy='category' for translated terms)")
|
|
for r in cat_rows:
|
|
desc = r['description'].replace("'", "''") if r['description'] else ''
|
|
sql_lines.append(
|
|
f"INSERT IGNORE INTO wp_term_taxonomy "
|
|
f"(term_taxonomy_id, term_id, taxonomy, description, parent, count) "
|
|
f"VALUES ({r['term_taxonomy_id']}, {r['term_id']}, 'category', "
|
|
f"'{desc}', {r['parent']}, {r['count']});"
|
|
)
|
|
sql_lines.append("")
|
|
|
|
# ─── 3. wp_term_taxonomy (language rows for translated terms) ────────────────
|
|
c.execute(f"""
|
|
SELECT term_taxonomy_id, term_id, taxonomy, description, parent, count
|
|
FROM wp_term_taxonomy
|
|
WHERE term_id IN ({ids_str}) AND taxonomy='language'
|
|
""")
|
|
lang_rows = c.fetchall()
|
|
sql_lines.append("-- 3. wp_term_taxonomy (taxonomy='language' for translated terms)")
|
|
for r in lang_rows:
|
|
desc = r['description'].replace("'", "''") if r['description'] else ''
|
|
sql_lines.append(
|
|
f"INSERT IGNORE INTO wp_term_taxonomy "
|
|
f"(term_taxonomy_id, term_id, taxonomy, description, parent, count) "
|
|
f"VALUES ({r['term_taxonomy_id']}, {r['term_id']}, 'language', "
|
|
f"'{desc}', {r['parent']}, {r['count']});"
|
|
)
|
|
sql_lines.append("")
|
|
|
|
# ─── 4. wp_term_taxonomy (term_translations groups for our ES categories) ───
|
|
# Get translation groups that contain any of our ES or translated term_ids
|
|
all_ids_str = ','.join(str(i) for i in all_es_ids + all_trans_ids)
|
|
c.execute("""
|
|
SELECT DISTINCT tt.term_taxonomy_id, tt.term_id, tt.taxonomy,
|
|
tt.description, tt.parent, tt.count
|
|
FROM wp_term_taxonomy tt
|
|
WHERE tt.taxonomy = 'term_translations'
|
|
""")
|
|
all_tt_rows = c.fetchall()
|
|
|
|
# Filter to only those that reference our category term_ids
|
|
relevant_tt = []
|
|
for r in all_tt_rows:
|
|
desc = r['description'] or ''
|
|
# Check if any of our term_ids appear in the description
|
|
for tid in all_es_ids + all_trans_ids:
|
|
if f'i:{tid};' in desc or f'i:{tid}' == desc.strip():
|
|
relevant_tt.append(r)
|
|
break
|
|
|
|
sql_lines.append("-- 4. wp_term_taxonomy (taxonomy='term_translations' groups for our categories)")
|
|
for r in relevant_tt:
|
|
desc = r['description'].replace("'", "''") if r['description'] else ''
|
|
sql_lines.append(
|
|
f"INSERT INTO wp_term_taxonomy "
|
|
f"(term_taxonomy_id, term_id, taxonomy, description, parent, count) "
|
|
f"VALUES ({r['term_taxonomy_id']}, {r['term_id']}, 'term_translations', "
|
|
f"'{desc}', {r['parent']}, {r['count']}) "
|
|
f"ON DUPLICATE KEY UPDATE description=VALUES(description), count=VALUES(count);"
|
|
)
|
|
sql_lines.append("")
|
|
|
|
# ─── 5. wp_terms for term_translations taxonomy entries ─────────────────────
|
|
tt_term_ids = [r['term_id'] for r in relevant_tt]
|
|
if tt_term_ids:
|
|
tt_ids_str = ','.join(str(i) for i in tt_term_ids)
|
|
c.execute(f"SELECT term_id, name, slug, term_group FROM wp_terms WHERE term_id IN ({tt_ids_str})")
|
|
tt_term_rows = c.fetchall()
|
|
# Insert before the term_taxonomy rows (we need to reorder — prepend)
|
|
term_inserts = []
|
|
for r in tt_term_rows:
|
|
name = r['name'].replace("'", "''")
|
|
slug = r['slug'].replace("'", "''")
|
|
term_inserts.append(
|
|
f"INSERT IGNORE INTO wp_terms (term_id, name, slug, term_group) "
|
|
f"VALUES ({r['term_id']}, '{name}', '{slug}', {r['term_group']});"
|
|
)
|
|
# Insert after section 1
|
|
idx = sql_lines.index("-- 2. wp_term_taxonomy (taxonomy='category' for translated terms)")
|
|
sql_lines[idx:idx] = ["-- 1b. wp_terms for term_translations taxonomy"] + term_inserts + [""]
|
|
|
|
# ─── 6. wp_term_relationships (post→translated category) ─────────────────────
|
|
# Get term_taxonomy_ids for translated categories
|
|
cat_tt_ids = [r['term_taxonomy_id'] for r in cat_rows]
|
|
if cat_tt_ids:
|
|
cat_tt_str = ','.join(str(i) for i in cat_tt_ids)
|
|
c.execute(f"""
|
|
SELECT object_id, term_taxonomy_id, term_order
|
|
FROM wp_term_relationships
|
|
WHERE term_taxonomy_id IN ({cat_tt_str})
|
|
ORDER BY term_taxonomy_id, object_id
|
|
""")
|
|
rel_rows = c.fetchall()
|
|
sql_lines.append("-- 5. wp_term_relationships (posts → translated categories)")
|
|
sql_lines.append(f"-- {len(rel_rows)} relationships")
|
|
# Batch INSERT for efficiency
|
|
if rel_rows:
|
|
batch = []
|
|
for r in rel_rows:
|
|
batch.append(f"({r['object_id']},{r['term_taxonomy_id']},{r['term_order']})")
|
|
if len(batch) >= 500:
|
|
sql_lines.append(
|
|
"INSERT IGNORE INTO wp_term_relationships (object_id, term_taxonomy_id, term_order) VALUES "
|
|
+ ','.join(batch) + ";"
|
|
)
|
|
batch = []
|
|
if batch:
|
|
sql_lines.append(
|
|
"INSERT IGNORE INTO wp_term_relationships (object_id, term_taxonomy_id, term_order) VALUES "
|
|
+ ','.join(batch) + ";"
|
|
)
|
|
sql_lines.append("")
|
|
|
|
# ─── 7. wp_term_relationships (translated terms → language taxonomy) ─────────
|
|
lang_tt_ids = [r['term_taxonomy_id'] for r in lang_rows]
|
|
if lang_tt_ids:
|
|
lang_tt_str = ','.join(str(i) for i in lang_tt_ids)
|
|
c.execute(f"""
|
|
SELECT object_id, term_taxonomy_id, term_order
|
|
FROM wp_term_relationships
|
|
WHERE term_taxonomy_id IN ({lang_tt_str})
|
|
""")
|
|
lang_rel_rows = c.fetchall()
|
|
sql_lines.append("-- 6. wp_term_relationships (translated category terms → language taxonomy)")
|
|
sql_lines.append(f"-- {len(lang_rel_rows)} relationships")
|
|
if lang_rel_rows:
|
|
batch = []
|
|
for r in lang_rel_rows:
|
|
batch.append(f"({r['object_id']},{r['term_taxonomy_id']},{r['term_order']})")
|
|
if len(batch) >= 500:
|
|
sql_lines.append(
|
|
"INSERT IGNORE INTO wp_term_relationships (object_id, term_taxonomy_id, term_order) VALUES "
|
|
+ ','.join(batch) + ";"
|
|
)
|
|
batch = []
|
|
if batch:
|
|
sql_lines.append(
|
|
"INSERT IGNORE INTO wp_term_relationships (object_id, term_taxonomy_id, term_order) VALUES "
|
|
+ ','.join(batch) + ";"
|
|
)
|
|
sql_lines.append("")
|
|
|
|
sql_lines.append("SET foreign_key_checks = 1;")
|
|
sql_lines.append("")
|
|
sql_lines.append("-- Done.")
|
|
|
|
db.close()
|
|
|
|
output = '\n'.join(sql_lines)
|
|
with open('/tmp/cat_translations_prod.sql', 'w', encoding='utf-8') as f:
|
|
f.write(output)
|
|
|
|
print(f"Written to /tmp/cat_translations_prod.sql")
|
|
print(f" {len(rows)} translated terms (wp_terms)")
|
|
print(f" {len(cat_rows)} category taxonomy rows")
|
|
print(f" {len(lang_rows)} language taxonomy rows")
|
|
print(f" {len(relevant_tt)} term_translations groups")
|
|
if cat_tt_ids:
|
|
print(f" {len(rel_rows)} post→category relationships")
|
|
if lang_tt_ids:
|
|
print(f" {len(lang_rel_rows)} term→language relationships")
|