odoo_utility_scripts/delete_zombie_constraint.py

87 lines
3.3 KiB
Python

import sys
import os
import argparse
import logging
def main():
parser = argparse.ArgumentParser(description="Drop Zombie Constraint 'product_pricelist_res_config_settin_res_config_settings_id_fkey'")
parser.add_argument("odoo_bin_path", help="Path to odoo-bin executable (e.g. odoo/odoo-bin)")
parser.add_argument("conf_path", help="Path to odoo.conf")
parser.add_argument("db_name", help="Database name")
args = parser.parse_args()
odoo_bin_path = os.path.abspath(args.odoo_bin_path)
conf_path = os.path.abspath(args.conf_path)
db_name = args.db_name
# Add Odoo to sys.path
odoo_root = os.path.dirname(odoo_bin_path)
if odoo_root not in sys.path:
sys.path.append(odoo_root)
# Change CWD to config directory to handle relative paths in config
os.chdir(os.path.dirname(conf_path))
try:
import odoo
from odoo import api, SUPERUSER_ID
except ImportError:
print(f"Error: Could not import 'odoo' module from {odoo_root}. Make sure odoo-bin path is correct.")
sys.exit(1)
print(f"Initializing Odoo Environment for database: {db_name}...")
try:
odoo.tools.config.parse_config(['-c', conf_path])
registry = odoo.registry(db_name)
except Exception as e:
print(f"Error initializing Odoo: {e}")
return
with registry.cursor() as cr:
env = api.Environment(cr, SUPERUSER_ID, {})
print("Connected to Odoo.")
# Define the problematic constraint connection
constraint_name = 'product_pricelist_res_config_settin_res_config_settings_id_fkey'
# Check if exists
cr.execute("""
SELECT conrelid::regclass::text
FROM pg_constraint
WHERE conname = %s
""", (constraint_name,))
result = cr.fetchone()
if result:
table_name = result[0]
print(f"Found constraint '{constraint_name}' on table '{table_name}'.")
try:
print(f"Dropping table '{table_name}'...")
cr.execute(f"DROP TABLE IF EXISTS {table_name} CASCADE")
print("Table dropped.")
# Double check constraint
cr.execute("SELECT count(*) FROM pg_constraint WHERE conname = %s", (constraint_name,))
if cr.fetchone()[0] == 0:
print("Constraint successfully removed.")
cr.commit()
else:
print("WARNING: Constraint still exists! Rolled back.")
cr.rollback()
except Exception as e:
print(f"Error dropping table/constraint: {e}")
cr.rollback()
else:
print(f"Constraint '{constraint_name}' not found. Database is likely clean.")
# Also invoke the hook logic just in case the name varies?
# The hook used 'DROP TABLE IF EXISTS product_pricelist_res_config_settings_rel CASCADE'
# Let's try that too.
print("Attempting to drop 'product_pricelist_res_config_settings_rel' blindly just in case...")
cr.execute("DROP TABLE IF EXISTS product_pricelist_res_config_settings_rel CASCADE")
print("Done.")
cr.commit()
if __name__ == "__main__":
main()