reset_db.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. """
  4. 数据库重置脚本
  5. 这个脚本用于清理数据库并准备新的迁移
  6. """
  7. import os
  8. import sys
  9. from sqlalchemy import text, inspect, create_engine
  10. import re
  11. import logging
  12. from sqlalchemy.ext.declarative import declarative_base
  13. # 配置日志
  14. logging.basicConfig(level=logging.INFO)
  15. logger = logging.getLogger(__name__)
  16. # 数据库连接信息
  17. DB_USER = "postgres"
  18. DB_PASSWORD = "123456789Qq"
  19. DB_HOST = "localhost"
  20. DB_PORT = "5432"
  21. DB_NAME = "soilgd"
  22. print(f"连接到数据库: {DB_USER}@{DB_HOST}:{DB_PORT}/{DB_NAME}")
  23. # 构建数据库连接URL
  24. SQLALCHEMY_DATABASE_URL = f"postgresql://{DB_USER}:{DB_PASSWORD}@{DB_HOST}:{DB_PORT}/{DB_NAME}"
  25. # 创建数据库引擎
  26. engine = create_engine(
  27. SQLALCHEMY_DATABASE_URL,
  28. pool_size=5,
  29. max_overflow=10,
  30. pool_timeout=30,
  31. pool_recycle=1800
  32. )
  33. # 要删除的表列表(按顺序)
  34. TABLES_TO_DROP = [
  35. 'fifty_thousand_survey_data',
  36. 'surveydata',
  37. 'unit_ceil',
  38. 'raster_table',
  39. 'Conventional_land_information',
  40. 'Point_information',
  41. 'alembic_version'
  42. ]
  43. # 不应该删除的系统表
  44. SYSTEM_TABLES = [
  45. 'spatial_ref_sys', # PostGIS系统表
  46. 'geography_columns',
  47. 'geometry_columns',
  48. 'raster_columns',
  49. 'raster_overviews'
  50. ]
  51. def get_all_tables():
  52. """获取数据库中所有表的名称(排除系统表)"""
  53. inspector = inspect(engine)
  54. tables = inspector.get_table_names()
  55. # 排除系统表
  56. return [t for t in tables if t not in SYSTEM_TABLES]
  57. def get_table_case_insensitive(table_name):
  58. """不区分大小写查找表名"""
  59. all_tables = get_all_tables()
  60. return [t for t in all_tables if t.lower() == table_name.lower()]
  61. def reset_database():
  62. """重置数据库,删除所有表"""
  63. print("\n==== 开始重置数据库 ====")
  64. # 获取删除前的所有表
  65. before_tables = get_all_tables()
  66. print(f"\n删除前的表: {before_tables}")
  67. try:
  68. for table_name in TABLES_TO_DROP:
  69. # 查找该表在数据库中的实际名称(考虑大小写)
  70. actual_tables = get_table_case_insensitive(table_name)
  71. if not actual_tables:
  72. print(f"表 '{table_name}' 不存在,跳过")
  73. continue
  74. for actual_table in actual_tables:
  75. try:
  76. with engine.begin() as conn:
  77. print(f"\n尝试删除表 '{actual_table}'...")
  78. # 使用双引号包裹表名以保持大小写
  79. sql = f'DROP TABLE IF EXISTS "{actual_table}" CASCADE'
  80. conn.execute(text(sql))
  81. print(f"执行SQL: {sql}")
  82. # 验证表是否已删除
  83. check_tables = get_table_case_insensitive(actual_table)
  84. if not check_tables:
  85. print(f"✓ 表 '{actual_table}' 已成功删除")
  86. else:
  87. print(f"✗ 表 '{actual_table}' 删除失败,仍然存在")
  88. except Exception as e:
  89. print(f"删除表 '{actual_table}' 时出错: {str(e)}")
  90. # 获取删除后的所有表
  91. after_tables = get_all_tables()
  92. print(f"\n==== 删除操作完成 ====")
  93. print(f"删除前的表: {len(before_tables)}个 - {before_tables}")
  94. print(f"删除后的表: {len(after_tables)}个 - {after_tables}")
  95. # 找出仍然存在的表
  96. remaining_tables = []
  97. for table in before_tables:
  98. # 检查表是否应该被删除
  99. should_be_deleted = any(re.match(f"^{t}$", table, re.IGNORECASE) for t in TABLES_TO_DROP)
  100. if should_be_deleted and table in after_tables:
  101. remaining_tables.append(table)
  102. if remaining_tables:
  103. print(f"\n警告:以下表应该被删除但仍然存在: {remaining_tables}")
  104. print("这可能是由于权限问题或者表依赖关系导致")
  105. else:
  106. print("\n所有目标表已成功删除")
  107. print("\n==== 数据库重置完成 ====")
  108. return 0
  109. except Exception as e:
  110. print(f"\n重置数据库时出错: {str(e)}")
  111. return 1
  112. if __name__ == '__main__':
  113. sys.exit(reset_database())