db_helper.py 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. """数据库操作辅助脚本,供 shell 同步脚本调用。"""
  4. import argparse
  5. import sys
  6. from pathlib import Path
  7. try:
  8. import pymysql
  9. except ImportError:
  10. print("ERROR: 需要安装 pymysql: pip install pymysql", file=sys.stderr)
  11. sys.exit(1)
  12. def connect_mysql(host, port, user, password, database):
  13. return pymysql.connect(
  14. host=host,
  15. port=int(port),
  16. user=user,
  17. password=password,
  18. database=database,
  19. charset="utf8mb4",
  20. autocommit=True,
  21. cursorclass=pymysql.cursors.Cursor,
  22. )
  23. def exec_sql_file(conn, sql_file):
  24. sql = Path(sql_file).read_text(encoding="utf-8")
  25. statements = [s.strip() for s in sql.split(";") if s.strip()]
  26. with conn.cursor() as cur:
  27. for stmt in statements:
  28. if stmt.upper().startswith("SET "):
  29. cur.execute(stmt)
  30. continue
  31. cur.execute(stmt)
  32. def exec_sql(conn, sql):
  33. with conn.cursor() as cur:
  34. cur.execute(sql)
  35. if cur.description:
  36. return cur.fetchall()
  37. return None
  38. def main():
  39. parser = argparse.ArgumentParser(description="MySQL 数据库辅助工具")
  40. parser.add_argument("--host", required=True)
  41. parser.add_argument("--port", default="3306")
  42. parser.add_argument("--user", required=True)
  43. parser.add_argument("--password", required=True)
  44. parser.add_argument("--database", required=True)
  45. sub = parser.add_subparsers(dest="action", required=True)
  46. p_file = sub.add_parser("file", help="执行 SQL 文件")
  47. p_file.add_argument("sql_file")
  48. p_query = sub.add_parser("query", help="执行单条 SQL 并输出结果")
  49. p_query.add_argument("sql")
  50. p_scalar = sub.add_parser("scalar", help="执行 SQL 并输出单个值")
  51. p_scalar.add_argument("sql")
  52. args = parser.parse_args()
  53. conn = connect_mysql(args.host, args.port, args.user, args.password, args.database)
  54. try:
  55. if args.action == "file":
  56. exec_sql_file(conn, args.sql_file)
  57. print("OK")
  58. elif args.action == "query":
  59. rows = exec_sql(conn, args.sql)
  60. for row in rows or []:
  61. print("\t".join("" if v is None else str(v) for v in row))
  62. elif args.action == "scalar":
  63. rows = exec_sql(conn, args.sql)
  64. if rows:
  65. print(rows[0][0])
  66. finally:
  67. conn.close()
  68. if __name__ == "__main__":
  69. main()