Django 2.2+Oracle数据库:检测并删除未使用的表与字段
检测并清理非Django管理的Oracle表
步骤1:获取Django模型对应的数据库表名
在Django Shell中执行以下代码,统一转为大写(适配Oracle默认的大写表名规则):
from django.apps import apps django_managed_tables = set() for model in apps.get_models(): # 转换为大写以匹配Oracle的表名存储格式 django_managed_tables.add(model._meta.db_table.upper())
步骤2:获取Oracle中所有用户表
执行Oracle SQL查询:
SELECT table_name FROM user_tables ORDER BY table_name;
步骤3:对比找出非Django管理的表
在Django Shell中结合数据库查询完成对比:
from django.db import connection with connection.cursor() as cursor: cursor.execute("SELECT table_name FROM user_tables") all_oracle_tables = set(row[0] for row in cursor.fetchall()) # 计算差值,得到非Django管理的表 unmanaged_tables = all_oracle_tables - django_managed_tables print("非Django管理的表:", unmanaged_tables)
清理非Django管理的表
确认这些表确实是无效表后,执行删除(注意先备份数据库):
-- 替换为实际表名,批量操作可生成脚本 DROP TABLE YOUR_TABLE_NAME CASCADE CONSTRAINTS;
检测并清理全量为NULL的无效字段
方法1:Oracle PL/SQL脚本批量检测与清理
执行以下PL/SQL脚本,会输出所有全NULL字段,确认后可开启删除逻辑:
SET SERVEROUTPUT ON; DECLARE non_null_count NUMBER; BEGIN -- 遍历所有用户表 FOR table_rec IN (SELECT table_name FROM user_tables) LOOP -- 遍历当前表的所有字段 FOR column_rec IN (SELECT column_name FROM user_tab_columns WHERE table_name = table_rec.table_name) LOOP -- 统计非NULL记录数 EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM ' || table_rec.table_name || ' WHERE ' || column_rec.column_name || ' IS NOT NULL' INTO non_null_count; IF non_null_count = 0 THEN DBMS_OUTPUT.PUT_LINE('无效字段:表 [' || table_rec.table_name || '] - 字段 [' || column_rec.column_name || ']'); -- 确认后取消注释,执行删除 -- EXECUTE IMMEDIATE 'ALTER TABLE ' || table_rec.table_name || ' DROP COLUMN ' || column_rec.column_name; END IF; END LOOP; END LOOP; END; /
方法2:Django脚本辅助检测
如果更熟悉Python,可在Django Shell中执行以下代码:
from django.db import connection with connection.cursor() as cursor: # 获取所有用户表 cursor.execute("SELECT table_name FROM user_tables") tables = [row[0] for row in cursor.fetchall()] for table in tables: # 获取当前表的所有字段 cursor.execute(f"SELECT column_name FROM user_tab_columns WHERE table_name = '{table}'") columns = [row[0] for row in cursor.fetchall()] for col in columns: # 统计非NULL行数 cursor.execute(f"SELECT COUNT(*) FROM {table} WHERE {col} IS NOT NULL") non_null_rows = cursor.fetchone()[0] if non_null_rows == 0: print(f"表 {table} 的字段 {col} 全为NULL") -- 确认后取消注释,执行删除 # cursor.execute(f"ALTER TABLE {table} DROP COLUMN {col}")
关键注意事项
- 操作前必须完整备份数据库,避免误删核心数据。
- 非Django管理的表中可能包含系统表或第三方工具生成的必要表,需人工确认后再删除。
- 删除字段前,需检查字段是否关联索引、外键等约束,可通过
user_constraints、user_indexes视图查询依赖关系。 - Django 2.2已停止官方维护,长期来看建议升级到受支持的版本。
内容的提问来源于stack exchange,提问作者Hamed Barati
相关产品推荐
相关产品推荐

