Files
wzdj/new/wz-api/scripts/mongo_to_wz_documents.py

83 lines
2.4 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python3
"""
将 MongoDB 导出的文档转为 MySQL `wz_documents` 的 INSERT SQL不依赖第三方库
步骤:
1) mongoexport与 old 集合名一致):
mongoexport --uri="$MONGO_URI" --collection=streamers --jsonArray -o streamers.json
2) 生成 SQL
python mongo_to_wz_documents.py --coll streamers --file streamers.json --out streamers.sql
3) 导入:
mysql -h ... -u ... -p dbname < streamers.sql
校验SELECT coll, COUNT(*) FROM wz_documents GROUP BY coll; 与 Mongo count 对照。
"""
from __future__ import annotations
import argparse
import json
import sys
from datetime import datetime, timezone
def oid_of(doc: dict) -> str:
_id = doc.get("_id")
if isinstance(_id, dict) and "$oid" in _id:
return str(_id["$oid"])
if isinstance(_id, str):
return _id
raise ValueError("无法解析 _id")
def load_docs(path: str) -> list[dict]:
with open(path, "r", encoding="utf-8") as f:
raw = f.read().strip()
if not raw:
return []
if raw[0] == "[":
data = json.loads(raw)
if not isinstance(data, list):
raise ValueError("JSON 根须为数组")
return data
return [json.loads(line) for line in raw.splitlines() if line.strip()]
def sql_escape(s: str) -> str:
return s.replace("\\", "\\\\").replace("'", "''")
def main() -> None:
ap = argparse.ArgumentParser()
ap.add_argument("--coll", required=True)
ap.add_argument("--file", required=True)
ap.add_argument("--out", required=True)
args = ap.parse_args()
docs = load_docs(args.file)
now = datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S")
lines = [
"-- generated by mongo_to_wz_documents.py",
"SET NAMES utf8mb4;",
"START TRANSACTION;",
]
for d in docs:
eid = oid_of(d)
body = json.dumps(d, ensure_ascii=False, separators=(",", ":"))
lines.append(
"INSERT INTO `wz_documents` (`coll`,`ext_id`,`body`,`created_at`,`updated_at`) VALUES ("
f"'{sql_escape(args.coll)}','{sql_escape(eid)}','{sql_escape(body)}','{now}','{now}')"
" ON DUPLICATE KEY UPDATE `body`=VALUES(`body`), `updated_at`=VALUES(`updated_at`);"
)
lines.append("COMMIT;")
with open(args.out, "w", encoding="utf-8") as f:
f.write("\n".join(lines) + "\n")
print(len(docs), "rows ->", args.out, file=sys.stderr)
if __name__ == "__main__":
main()