- vm_store: MySQL (PyMySQL) default backend, SQLite fallback - CDR: cdr_adaptive_odbc + res_odbc + MariaDB ODBC driver + Master.csv backfill - contacts: full E.164 matching, WORK-email preference, junk-name guard - backfill scripts: vm_migrate_sqlite_to_mysql.py, vm_backfill_contacts.py, vm_backfill_cdr.py - live: 131 messages migrated, 7591 CDR rows backfilled
80 lines
2.5 KiB
Python
80 lines
2.5 KiB
Python
#!/usr/bin/env python3
|
|
"""One-shot: migrate the SQLite voicemail store into MySQL.
|
|
|
|
Reads the existing /var/lib/vm-transcribe/voicemail.db (sqlite) and inserts
|
|
every message/setting/session row into the MySQL `asterisk` DB, skipping
|
|
duplicates on (mailbox, origtime, callerid). Idempotent.
|
|
|
|
Run as asterisk:
|
|
sudo -u asterisk /opt/vm-transcribe/venv/bin/python3 /opt/vm-transcribe/vm_migrate_sqlite_to_mysql.py
|
|
"""
|
|
import json
|
|
import os
|
|
import sqlite3
|
|
import sys
|
|
|
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
import vm_store
|
|
|
|
SRC = os.environ.get("VM_DB", "/var/lib/vm-transcribe/voicemail.db")
|
|
|
|
|
|
def main():
|
|
if not os.path.exists(SRC):
|
|
print("no sqlite source at", SRC, "- nothing to migrate")
|
|
return
|
|
src = sqlite3.connect(SRC)
|
|
src.row_factory = sqlite3.Row
|
|
|
|
dst = vm_store.connect() # MySQL (via secret)
|
|
print("migrating from", SRC, "-> MySQL")
|
|
|
|
cols = [d[1] for d in src.execute("PRAGMA table_info(messages)")]
|
|
n = 0
|
|
for r in src.execute("SELECT * FROM messages"):
|
|
try:
|
|
vals = []
|
|
for c in cols:
|
|
v = r[c]
|
|
if c in ("intents", "numbers") and isinstance(v, str):
|
|
try:
|
|
json.loads(v)
|
|
except Exception:
|
|
v = json.dumps([])
|
|
vals.append(v)
|
|
ph = ",".join(["%s"] * len(cols))
|
|
dst.execute(
|
|
"INSERT IGNORE INTO messages (%s) VALUES (%s)" %
|
|
(",".join(cols), ph), vals)
|
|
n += 1
|
|
except Exception as e:
|
|
print(" skip msg id", r["id"], ":", e)
|
|
dst.commit()
|
|
print("messages scanned: %d" % n)
|
|
|
|
for tbl in ("settings", "sessions"):
|
|
try:
|
|
c = [d[1] for d in src.execute("PRAGMA table_info(%s)" % tbl)]
|
|
except Exception:
|
|
continue
|
|
k = 0
|
|
for r in src.execute("SELECT * FROM %s" % tbl):
|
|
try:
|
|
dst.execute(
|
|
"INSERT IGNORE INTO %s (%s) VALUES (%s)" %
|
|
(tbl, ",".join(c), ",".join(["%s"] * len(c))),
|
|
[r[x] for x in c])
|
|
k += 1
|
|
except Exception as e:
|
|
print(" skip %s row:" % tbl, e)
|
|
dst.commit()
|
|
print("%s migrated: %d" % (tbl, k))
|
|
|
|
# quick count check
|
|
total = dst.execute("SELECT COUNT(*) c FROM messages").fetchone()["c"]
|
|
print("MySQL messages total: %d" % total)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|