This system provides a dynamic approach to manage PostgreSQL database triggers for automatic actions like:
- Auto-creating wallets when users are created
- Auto-updating timestamps
- Auto-updating post statistics
- And more...
from src.db.postgres.setup_triggers import setup_all_triggers
# Setup all predefined triggers
results = setup_all_triggers()
print(f"Created {results['triggers_created']} triggers")
print(f"Success: {results['success']}")
print(f"Failed: {results['failed']}")from src.db.postgres.postgres import connection
from src.db.postgres.triggers import setup_user_wallet_trigger
trigger_manager = connection.get_trigger_manager()
# Auto-create wallet when user is created
setup_user_wallet_trigger(trigger_manager)Automatically creates a wallet with default values when a new user is created.
from src.db.postgres.triggers import setup_user_wallet_trigger
trigger_manager = connection.get_trigger_manager()
setup_user_wallet_trigger(trigger_manager)Default Values:
balance_credits: 0.0balance_points: 20.0ads_credits: 0.0
Automatically updates the last_updated timestamp when a record is updated.
from src.db.postgres.triggers import setup_updated_at_trigger
trigger_manager = connection.get_trigger_manager()
setup_updated_at_trigger(trigger_manager, "user")
setup_updated_at_trigger(trigger_manager, "posts")Automatically updates post-related statistics when posts are inserted or deleted.
from src.db.postgres.triggers import setup_post_auto_update_trigger
trigger_manager = connection.get_trigger_manager()
setup_post_auto_update_trigger(trigger_manager, "posts")from src.db.postgres.setup_triggers import create_custom_trigger
from src.db.postgres.triggers import TriggerEvent
function_body = """
-- Update post like count
IF TG_OP = 'INSERT' THEN
UPDATE posts
SET likes_count = COALESCE(likes_count, 0) + 1
WHERE id = NEW.post_id;
ELSIF TG_OP = 'DELETE' THEN
UPDATE posts
SET likes_count = GREATEST(COALESCE(likes_count, 0) - 1, 0)
WHERE id = OLD.post_id;
END IF;
RETURN COALESCE(NEW, OLD);
"""
create_custom_trigger(
trigger_name="auto_update_post_likes_count",
table_name="post_likes",
function_body=function_body,
event=TriggerEvent.AFTER_INSERT
)from src.db.postgres.triggers import TriggerManager, TriggerEvent
trigger_manager = connection.get_trigger_manager()
# Create function
function_body = """
-- Only update if status changed
IF OLD.status != NEW.status THEN
INSERT INTO status_history (record_id, old_status, new_status, changed_at)
VALUES (NEW.id, OLD.status, NEW.status, NOW());
END IF;
RETURN NEW;
"""
trigger_manager.create_trigger_function("track_status_changes", function_body)
# Create trigger with condition
trigger_manager.create_trigger(
trigger_name="trigger_status_change",
table_name="posts",
function_name="track_status_changes",
event=TriggerEvent.AFTER_UPDATE,
condition="OLD.status IS DISTINCT FROM NEW.status"
)from src.db.postgres.setup_triggers import list_all_triggers
# List all triggers
all_triggers = list_all_triggers()
# List triggers for specific table
user_triggers = list_all_triggers("user")
for trigger in user_triggers:
print(f"{trigger['trigger_name']} on {trigger['table_name']}")from src.db.postgres.setup_triggers import drop_trigger
drop_trigger("trigger_auto_create_wallet_on_user_insert", "user")from src.db.postgres.postgres import connection
from src.db.postgres.triggers import TriggerManager, TriggerEvent, TriggerFunctions
trigger_manager = connection.get_trigger_manager()
# Create custom function
function_body = TriggerFunctions.auto_update_updated_at()
trigger_manager.create_trigger_function("my_custom_function", function_body)
# Create trigger
trigger_manager.create_trigger(
trigger_name="my_trigger",
table_name="my_table",
function_name="my_custom_function",
event=TriggerEvent.BEFORE_UPDATE
)Available trigger events from TriggerEvent enum:
BEFORE_INSERT- Before a new row is insertedAFTER_INSERT- After a new row is insertedBEFORE_UPDATE- Before a row is updatedAFTER_UPDATE- After a row is updatedBEFORE_DELETE- Before a row is deletedAFTER_DELETE- After a row is deleted
The TriggerFunctions class provides ready-to-use trigger functions:
auto_create_wallet_on_user_insert()- Creates wallet for new userauto_update_updated_at()- Updates last_updated timestampauto_update_post_stats()- Updates post statisticslog_audit_trail()- Logs changes to audit table
- Always check if trigger exists before creating to avoid duplicates
- Use meaningful names for triggers and functions
- Test triggers in development before deploying to production
- Document custom triggers in your codebase
- Use transactions when creating multiple triggers
-
Check if trigger exists:
triggers = list_all_triggers("user")
-
Check trigger function:
SELECT proname, prosrc FROM pg_proc WHERE proname = 'your_function_name';
-
Check for errors in PostgreSQL logs
- Check the trigger function syntax
- Ensure all referenced columns exist
- Check data types match
- Verify foreign key constraints
You can run the setup script directly:
cd api
python -m src.db.postgres.setup_triggersOr import and use:
from src.db.postgres.setup_triggers import setup_all_triggers
if __name__ == "__main__":
results = setup_all_triggers()
print(f"Setup complete: {results}")You can initialize triggers when your application starts:
# In your server.py or main application file
from src.db.postgres.setup_triggers import setup_all_triggers
@app.on_event("startup")
async def startup_event():
"""Initialize database triggers on startup"""
logger.info("Setting up database triggers...")
results = setup_all_triggers()
logger.info(f"Database triggers setup complete: {results}")