Skip to content

Add analytics dashboard with detokenization queries and visualizations using SQL Warehouse - #8

Merged
samsternberg merged 1 commit into
mainfrom
databricks-classic-sql
Dec 21, 2025
Merged

samsternberg merged 1 commit into
mainfrom
databricks-classic-sql

Conversation

@samsternberg

Copy link
Copy Markdown
Contributor

No description provided.

@samsternberg
samsternberg merged commit 018471e into main Dec 21, 2025
1 check passed
@claude

claude Bot commented Dec 21, 2025

Copy link
Copy Markdown

Pull Request Review: Analytics Dashboard with Detokenization

This PR adds comprehensive analytics dashboard examples demonstrating SQL-based detokenization and visualization capabilities. Overall, this is a high-quality addition that significantly enhances the Databricks integration documentation with practical, production-ready examples.


✅ Strengths

1. Excellent Documentation & User Experience

  • Clear, progressive examples from simple queries to complex visualizations
  • Helpful explanatory text with security warnings where appropriate
  • Multiple export options (notebook, HTML, Lakeview JSON) cater to different use cases
  • Visual output using display() and displayHTML() provides immediate feedback

2. Strong Security Awareness

  • Explicit warnings about PII detokenization (⚠️ symbols, security reminders)
  • Recommends Unity Catalog permissions for access control
  • Separates tokenized vs. detokenized views in guidance
  • References Skyflow governance engine and audit logs

3. Well-Structured SQL Queries

  • CTEs used appropriately for readability
  • Efficient batched detokenization leveraging existing UDFs
  • Mix of tokenized-only and detokenized queries demonstrates flexibility
  • Proper use of catalog/schema references

4. Production-Ready Patterns

  • HTML dashboard with professional styling and responsive design
  • Lakeview JSON export enables one-click import
  • Multiple deployment methods (scheduled notebooks, SQL dashboards, Databricks Apps)
  • Realistic metrics and visualizations for business stakeholders

🔍 Issues & Recommendations

1. SQL Function Compatibility Issue (Critical)

Location: Cells 14, 16, 18, 21

Problem: The SQL queries use SUBSTRING_INDEX() which is not a standard Spark SQL function. This function exists in MySQL/MariaDB but will fail in Databricks.

-- ❌ This will fail in Databricks:
SUBSTRING_INDEX(email, '@', -1) as email_domain

Impact: All email domain analysis queries will fail when users run the notebook.

Fix: Replace with standard Spark SQL syntax:

-- ✅ Correct Spark SQL syntax:
SPLIT(email, '@')[1] as email_domain

-- Or using element_at() for better null handling:
element_at(SPLIT(email, '@'), -1) as email_domain

Affected Cells:

  • Cell 14: Domain distribution query (2 occurrences)
  • Cell 16: Domain visualization query
  • Cell 18: HTML dashboard query
  • Cell 21: Lakeview JSON dataset definition

2. Python Syntax Error in HTML Dashboard (Critical)

Location: Cell 18

Problem: The f-string uses nested curly braces for CSS which will cause Python syntax errors:

html = f"""
<style>
    body {{
        font-family: -apple-system, ...;
        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    }}

While double braces {{}} escape correctly for most cases, the percentage values inside gradients might cause issues depending on Python version.

Fix: Use proper escaping or consider triple-brace escaping for nested structures:

# Option 1: Ensure all CSS curly braces are doubled
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);  # Should work

# Option 2: Build HTML without f-string if escaping becomes complex
html = """...""".format(...)

Testing Needed: This cell should be tested to ensure the HTML renders correctly.


3. Hardcoded File Path Limitation

Location: Cell 21

Problem: The dashboard JSON generation writes to /tmp/skyflow_analytics_dashboard.lvdash.json which may not persist across cluster restarts or be accessible in all Databricks environments.

tmp_path = "/tmp/skyflow_analytics_dashboard.lvdash.json"
with open(tmp_path, 'w') as f:
    f.write(dashboard_json_str)

Recommendations:

  1. The commented-out DBFS option is better for persistence
  2. Consider using dbutils.fs.put() directly instead of copying from /tmp
  3. Add error handling for file write operations
  4. Document that /tmp files are ephemeral

Suggested improvement:

# Print JSON to notebook output (always works)
print(dashboard_json_str)

# Optionally save to DBFS if dbutils available
try:
    dbfs_path = "dbfs:/FileStore/skyflow/skyflow_analytics_dashboard.lvdash.json"
    dbutils.fs.put(dbfs_path, dashboard_json_str, overwrite=True)
    print(f"✓ Saved to DBFS: {dbfs_path}")
except Exception as e:
    print(f"⚠️  Could not save to DBFS (optional): {e}")

4. Incomplete Lakeview JSON Structure

Location: Cell 21 (visible in diff truncation)

Problem: The PR diff shows the Lakeview JSON structure is truncated with "... [8 lines truncated] ..." which suggests the dashboard definition may be incomplete.

Impact: The dashboard might not import correctly into Databricks SQL if the JSON is malformed or incomplete.

Recommendation:

  • Verify the complete JSON structure is valid
  • Test the import process in Databricks SQL
  • Consider validating JSON schema before saving
  • Add instructions for troubleshooting import failures

5. Missing Error Handling

Location: Cell 18 (HTML dashboard data fetching)

Problem: The queries use .collect()[0] which will raise an IndexError if no data exists:

metrics_data = spark.sql(...).collect()[0]  # ❌ Fails if empty result
domain_data = spark.sql(...).collect()       # ✓ Safe, but should check length

Fix:

# Add safety checks
result = spark.sql(...).collect()
if not result:
    raise ValueError("No data found in tokenized_users table. Run previous cells first.")
metrics_data = result[0]

# For domain_data, check before using in loop
domain_data = spark.sql(...).collect()
if not domain_data:
    print("⚠️  No domain data available for visualization")

6. Inconsistent Markdown Formatting

Location: Cell metadata

Problem: Markdown cells show <cell_type>markdown</cell_type> in the structure, but the actual Jupyter notebook format should use "cell_type": "markdown" in JSON.

Impact: This is likely a display artifact from the Read tool, but should be verified that the actual .ipynb file is valid JSON.

Recommendation: Validate the notebook JSON structure:

python -m json.tool samples/databricks.ipynb > /dev/null && echo "Valid JSON" || echo "Invalid JSON"

🎯 Performance Considerations

Positive Aspects:

  1. Efficient batching: Reuses existing UDFs with configured batch sizes (500 to Lambda → 25 to Skyflow)
  2. Smart query design: Separates tokenized-only analytics from detokenized queries
  3. Limited detokenization scope: Only detokenizes when necessary for domain analysis or display

Potential Optimizations:

  1. Cache intermediate results: Consider caching the detokenized CTE for reuse:

    CREATE TEMP VIEW detokenized_emails_cached AS
    SELECT user_id, skyflow_detokenize(email_token) as email
    FROM tokenized_users;
    CACHE TABLE detokenized_emails_cached;
  2. Limit result sets: Some queries don't have LIMIT clauses and will detokenize all records. Consider adding:

    -- Add LIMIT or TOP N to reduce API calls
    LIMIT 1000  -- or appropriate business requirement

🔒 Security Considerations

Well Implemented:

  • ✅ Explicit security warnings on cells that detokenize PII
  • ✅ References Unity Catalog access control throughout
  • ✅ Recommends separate dashboards for tokenized vs. detokenized views
  • ✅ Mentions audit logging capabilities

Enhancement Opportunities:

  1. Add redaction policy reminder: Mention that Skyflow's governance engine can apply column-level redaction even after detokenization calls (per CLAUDE.md guidance)

  2. Data residency warning: For HTML dashboards that embed detokenized data, add a note that the HTML contains plaintext PII and should be handled accordingly:

    print("⚠️  SECURITY WARNING: The generated HTML contains plaintext PII.")
    print("   - Do not share the HTML file outside authorized channels")
    print("   - Consider using Databricks SQL dashboards instead for dynamic, governed access")
  3. Add query parameter example: Show how to use redactionType for controlled detokenization:

    # Example with redaction control (mentioned in CLAUDE.md but not demonstrated)
    resp = requests.post(
        LAMBDA_URL,
        json={{"tokens": tokens, "options": {{"redactionType": "MASKED"}}}},
        ...
    )

📊 Code Quality

Strengths:

  • Consistent formatting and style
  • Clear variable naming
  • Good use of constants (CATALOG, SCHEMA)
  • Helpful print statements for user feedback

Minor Improvements:

  1. Cell 14 & 16: Reduce code duplication by extracting common query patterns into a helper function

  2. Cell 21: The dashboard JSON structure is very verbose. Consider:

    • Breaking into logical sections with comments
    • Using helper functions to generate repeated widget structures
    • Validating against Databricks schema if available
  3. String interpolation consistency: Mix of f-strings and .format(). Stick with f-strings throughout for consistency.


🧪 Testing Coverage

Missing Tests:

This PR adds example code but no automated tests. Consider adding:

  1. Integration test: Verify queries execute successfully against test data
  2. JSON validation: Ensure Lakeview JSON is well-formed and importable
  3. SQL syntax test: Validate all SQL queries parse correctly
  4. HTML rendering test: Verify HTML dashboard displays without errors

Suggested Test Structure:

# Add to a new test cell at the end
def test_dashboard_queries():
    """Verify all dashboard queries execute without errors"""
    try:
        # Test query 1
        result = spark.sql(f"""...""")
        assert result.count() >= 0
        print("✓ Query 1 passed")
        
        # Test query 2
        # ...
    except Exception as e:
        print(f"✗ Test failed: {e}")
        raise

test_dashboard_queries()

📝 Documentation Quality

Excellent:

  • Progressive complexity (simple → advanced)
  • Multiple export methods documented
  • Security best practices included
  • Real-world use cases explained

Suggestions:

  1. Add troubleshooting section: Common errors and solutions (e.g., "Function not found" → check cell execution order)

  2. Prerequisites checklist: Add a cell at the top that validates:

    • Unity Catalog functions exist
    • Test data is populated
    • Required permissions are granted
  3. Video or screenshot references: Mention where users can find Databricks SQL dashboard import UI (helpful for first-time users)


🎬 Final Recommendations

Must Fix Before Merge:

  1. Replace SUBSTRING_INDEX() with SPLIT()[1] in all queries (Critical)
  2. Verify HTML f-string escaping doesn't cause syntax errors (Critical)
  3. Complete the truncated Lakeview JSON structure (Critical)
  4. Add error handling for .collect()[0] operations (High)

Should Fix Before Merge:

  1. Add security warning about HTML containing plaintext PII (Medium)
  2. Document /tmp file limitations and recommend DBFS alternative (Medium)
  3. Add basic integration test cell at the end (Medium)

Nice to Have:

  1. Add query result caching example for performance
  2. Extract common query patterns to reduce duplication
  3. Add troubleshooting section for common errors

🌟 Overall Assessment

Score: 8/10

This is a strong contribution that will significantly benefit users by showing practical, real-world analytics patterns. The dashboard examples are well-designed and production-ready. However, the critical SQL syntax error (SUBSTRING_INDEX) must be fixed before merge, as it will cause immediate failures for users.

Summary:

  • Code Quality: ✅ Excellent (aside from SQL syntax issue)
  • Documentation: ✅ Excellent
  • Security: ✅ Good (minor enhancements suggested)
  • Testing: ⚠️ Missing (should add basic tests)
  • Performance: ✅ Good
  • Production Ready: ⚠️ After fixing critical issues

Recommendation: Request changes to fix the critical SQL syntax error, then approve. This will be a valuable addition to the repository.


🤝 Conclusion

Thank you for this comprehensive addition! The analytics dashboard examples will help users understand how to build production data pipelines with Skyflow tokenization. Once the SQL syntax issues are resolved, this will be ready to merge.

Please feel free to reach out if you have questions about any of these suggestions!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant