splurge-sql-runner


Namesplurge-sql-runner JSON
Version 2025.4.0 PyPI version JSON
download
home_pageNone
SummaryA Python utility for executing SQL files against databases with support for multiple statements, comments, and pretty-printed results
upload_time2025-08-24 21:42:16
maintainerJim Schilling
docs_urlNone
authorJim Schilling
requires_python>=3.10
licenseNone
keywords sql database cli sqlalchemy sqlite postgresql mysql
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # splurge-sql-runner
Splurge Python SQL Runner

A Python utility for executing SQL files against databases with support for multiple statements, comments, and pretty-printed results.

## Features

- Execute SQL files with multiple statements
- Support for various database backends (SQLite, PostgreSQL, MySQL, etc.)
- Automatic comment removal and statement parsing
- Pretty-printed results with tabulated output
- Batch processing of multiple files
- Batch SQL execution with error handling
- Clean CLI interface with comprehensive error handling
- Security validation for database URLs and file operations
- Configuration management with JSON-based config files
- Configurable logging for CLI usage (level, format, console/file output)

## Installation

```bash
pip install splurge-sql-runner
```

## CLI Usage

The main interface is through the command-line tool:

### Basic Usage

```bash
# Execute a single SQL file
python -m splurge_sql_runner -c "sqlite:///database.db" -f "script.sql"

# Execute multiple SQL files using a pattern
python -m splurge_sql_runner -c "sqlite:///database.db" -p "*.sql"

# With verbose output
python -m splurge_sql_runner -c "sqlite:///database.db" -f "script.sql" -v

# Using the installed script (after pip install)
splurge-sql-runner -c "sqlite:///database.db" -f "script.sql"

# Load with a JSON config file
python -m splurge_sql_runner --config config.json -c "sqlite:///database.db" -f "script.sql"

# Output as JSON (for scripting)
python -m splurge_sql_runner -c "sqlite:///database.db" -f "script.sql" --json

# Disable emoji (useful on limited consoles)
python -m splurge_sql_runner -c "sqlite:///database.db" -f "script.sql" --no-emoji

# Continue executing statements after an error (per-file)
python -m splurge_sql_runner -c "sqlite:///database.db" -f "script.sql" --continue-on-error
```

### Command Line Options

- `-c, --connection`: Database connection string (required)
  - SQLite: `sqlite:///database.db`
  - PostgreSQL: `postgresql://user:pass@localhost/db`
  - MySQL: `mysql://user:pass@localhost/db`
  
- `-f, --file`: Single SQL file to execute
  
- `-p, --pattern`: File pattern to match multiple SQL files (e.g., "*.sql")
  
- `-v, --verbose`: Enable verbose output
  
- `--debug`: Enable SQLAlchemy debug mode (SQLAlchemy echo)

- `--config FILE`: Path to JSON config file. Values from the file are merged with defaults and overridden
  by any CLI arguments.

- `--json`: Output results as JSON (machine-readable).

- `--no-emoji`: Replace emoji glyphs with ASCII tags in output.

- `--continue-on-error`: Continue processing remaining statements after an error (default is stop on first error).

Security validation cannot be disabled. If stricter defaults block your use case, adjust `SecurityConfig` in your JSON config (e.g., `security.max_statements_per_file`, `security.allowed_file_extensions`, or dangerous pattern lists) and rerun.

- `--max-statements`: Maximum statements per file (default: 100)

### Examples

```bash
# SQLite example
python -m splurge_sql_runner -c "sqlite:///test.db" -f "setup.sql"

# PostgreSQL example
python -m splurge_sql_runner -c "postgresql://user:pass@localhost/mydb" -p "migrations/*.sql"

# MySQL example with verbose output
python -m splurge_sql_runner -c "mysql://user:pass@localhost/mydb" -f "data.sql" -v

# Process all SQL files in current directory
python -m splurge_sql_runner -c "sqlite:///database.db" -p "*.sql"

# Adjust security via config (example)
# config.json
#{
#  "security": {
#    "max_statements_per_file": 500,
#    "allowed_file_extensions": [".sql", ".ddl"]
#  }
#}
python -m splurge_sql_runner -c "sqlite:///database.db" -f "script.sql"
```

## Security Tuning

Security is enforced by default. If your workflow requires broader allowances, tune these fields in your
JSON configuration file:

- `security.max_statements_per_file` (int): Maximum SQL statements allowed per file. Increase if you run
  bulk scripts. CLI also accepts `--max-statements` to override per run.
- `security.validation.max_statement_length` (int): Maximum size in characters for a single statement.
- `security.allowed_file_extensions` (list[str]): Allowed extensions for SQL files (e.g., `[".sql", ".ddl"]`).
- `security.validation.dangerous_sql_patterns` (list[str]): Substrings considered dangerous in SQL. Remove
  or modify with caution.
- `security.validation.dangerous_path_patterns` (list[str]): Path substrings that are blocked for file safety.
- `security.validation.dangerous_url_patterns` (list[str]): Connection URL substrings that are blocked.

Example minimal config to relax limits:

```json
{
  "security": {
    "max_statements_per_file": 500,
    "allowed_file_extensions": [".sql", ".ddl"],
    "validation": {
      "max_statement_length": 200000
    }
  }
}
```

## Logging Behavior

Logging is configured via the `logging` section in your JSON config and is applied automatically on startup:

- `logging.level`: One of `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`.
- `logging.format`: `TEXT` (human-readable) or `JSON`.
- `logging.enable_console`: Whether to log to console.
- `logging.enable_file`: Whether to log to a file.
- `logging.log_file`/`logging.log_dir`: Exact file or directory to write logs. If only `log_dir` is provided, a default filename is used.
- `logging.backup_count`: Number of daily-rotated log files to keep.

CLI will bootstrap minimal logging with default values and then reconfigure using your JSON config (if provided) before running.

## Notes on paths and patterns

- The `--file` path is expanded with `~` (home) and resolved to an absolute path before use.
- The `--pattern` is expanded for `~` and matched with glob; matched files are resolved to absolute paths.

## Programmatic Usage

**Note**: This library is primarily designed to be used via the CLI interface. The programmatic API is provided for advanced use cases and integration scenarios, but the CLI offers the most comprehensive features and best user experience.

### Basic Usage

```python
from splurge_sql_runner.database.database_client import DatabaseClient
from splurge_sql_runner.config.database_config import DatabaseConfig

client = DatabaseClient(DatabaseConfig(url="sqlite:///database.db"))

try:
    results = client.execute_batch("SELECT 1;")
    for r in results:
        print(r)
finally:
    client.close()
```

### Advanced Usage

```python
from splurge_sql_runner.config import AppConfig
from splurge_sql_runner.database import DatabaseClient

config = AppConfig.load("config.json")

client = DatabaseClient(config.database)

try:
    results = client.execute_batch("SELECT 1; INSERT INTO test VALUES (1);")
    for result in results:
        print(f"Statement type: {result['statement_type']}")
        if result['statement_type'] == 'fetch':
            print(f"Rows returned: {result['row_count']}")
finally:
    client.close()
```



## Configuration

The library supports JSON-based configuration files for advanced usage:

```json
{
    "database": {
        "url": "sqlite:///database.db",
        "connection": {
            "timeout": 30
        },
        "enable_debug": false
    },
    "security": {
        "enable_validation": true,
        "max_statements_per_file": 100
    },
    "logging": {
        "level": "INFO",
        "format": "TEXT",
        "enable_console": true,
        "enable_file": false
    }
}
```

## SQL File Format

The tool supports SQL files with:
- Multiple statements separated by semicolons
- Single-line comments (`-- comment`)
- Multi-line comments (`/* comment */`)
- Comments within string literals are preserved

Example SQL file:
```sql
-- Create table
CREATE TABLE users (
    id INTEGER PRIMARY KEY,
    name TEXT NOT NULL
);

-- Insert data
INSERT INTO users (name) VALUES ('John');
INSERT INTO users (name) VALUES ('Jane');

-- Query data
SELECT * FROM users;
```

## Output Format

The CLI provides formatted output showing:
- File being processed
- Each statement executed
- Results in tabulated format for SELECT queries
- Success/error status for each statement
- Summary of files processed

## Error Handling

- Individual statement errors don't stop the entire batch
- Failed statements are reported with error details
- Database connections are properly cleaned up
- Exit codes indicate success/failure
- (Removed) Circuit breaker/retry error-recovery layers in favor of simple CLI errors
- Security validation with configurable thresholds

## License

MIT License - see LICENSE file for details.

## Development

### Installation for Development

```bash
# Clone the repository
git clone https://github.com/jim-schilling/splurge-sql-runner.git
cd splurge-sql-runner

# Install in development mode with all dependencies
pip install -e ".[dev]"

# Run tests
pytest -x -v

# Run linting
flake8 splurge_sql_runner/
black splurge_sql_runner/
mypy splurge_sql_runner/
```

## Changelog

### 2025.4.0 (08-24-2025)

- **Performance & Code Quality**: Optimized and simplified `sql_helper.py` module
  - **Reduced complexity**: Eliminated 5 helper functions and consolidated keyword sets
  - **Better performance**: Implemented O(1) set membership checks and unified CTE scanner
  - **Cleaner code**: Single token normalization and simplified control flow
  - **Accurate documentation**: Removed misleading caching claims from docstrings
  - **Reduced maintenance burden**: Removed unused `ERROR_STATEMENT` constant and helpers
  - **Bug fix**: Enhanced comment filtering in `parse_sql_statements` for edge cases
- **Backward Compatibility**: All public APIs remain unchanged, no breaking changes
- **Test Coverage**: Maintained 93% test coverage with all existing functionality preserved
- **Documentation**: Created comprehensive optimization plan in `plans/sql_helper_optimization_plan.md`
- **Verification**: All examples and tests continue to work correctly after optimization

### 2025.3.1 (08-20-2025)

- **Test Coverage**: Improved test coverage to 85% target across core modules
  - `sql_helper.py`: Reached 85% coverage with comprehensive edge case testing
  - `database_client.py`: Improved from ~71% to 77% coverage with additional test scenarios
  - `cli.py`: Reached 84% coverage with enhanced CLI functionality testing
- **Test Quality**: Added behavior-driven tests focusing on public APIs and real functionality
  - Enhanced CTE (Common Table Expressions) parsing edge cases
  - Added DCL (Data Control Language) statement type detection
  - Improved error handling and rollback behavior testing
  - Added config file handling and security guidance output tests
  - Enhanced pattern matching and multi-file processing scenarios
- **Code Quality**: Moved all import statements to top of modules where possible
  - Cleaned up inline imports in test files (`test_cli.py`, `conftest.py`, `test_logging_performance.py`)
  - Removed duplicate test functions that were accidentally created
  - Maintained appropriate inline imports for test setup methods where needed
- **Documentation**: Created comprehensive test improvement plan in `plans/improve-code-coverage.md`
- **Testing**: Verified all examples work correctly with enhanced test suite
  - Interactive demo functionality confirmed working
  - CLI automation tests passing
  - Database deployment script execution verified
  - Pattern matching and JSON output features tested

### 2025.3.0 (08-11-2025)

- **Documentation**: Updated Programmatic Usage section to clarify that the library is primarily designed for CLI usage
- **Documentation**: Added note explaining that programmatic API is for advanced use cases and integration scenarios
- **Documentation**: Emphasized that CLI offers the most comprehensive features and best user experience
- **Breaking Changes**: Unified engine abstraction replaced by `DatabaseClient`
- **New**: Centralized configuration constants in `splurge_sql_runner.config.constants`
- **Improved**: Security validation now uses centralized `SecurityConfig` from `splurge_sql_runner.config.security_config`
- **Code Quality**: Eliminated code duplication across the codebase
- **Breaking Changes**: Environment variables now use `SPLURGE_SQL_RUNNER_` prefix instead of `JPY_`
  - `JPY_DB_URL` → `SPLURGE_SQL_RUNNER_DB_URL`
  - `JPY_DB_TIMEOUT` → `SPLURGE_SQL_RUNNER_DB_TIMEOUT`
  - `JPY_SECURITY_ENABLED` → `SPLURGE_SQL_RUNNER_SECURITY_ENABLED`
  - `JPY_MAX_FILE_SIZE_MB` → `SPLURGE_SQL_RUNNER_MAX_FILE_SIZE_MB`
  - `JPY_MAX_STATEMENTS_PER_FILE` → `SPLURGE_SQL_RUNNER_MAX_STATEMENTS_PER_FILE`
  - `JPY_VERBOSE` → `SPLURGE_SQL_RUNNER_VERBOSE`
  - `JPY_LOG_LEVEL` → `SPLURGE_SQL_RUNNER_LOG_LEVEL`
  - `JPY_LOG_FORMAT` → `SPLURGE_SQL_RUNNER_LOG_FORMAT`


            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "splurge-sql-runner",
    "maintainer": "Jim Schilling",
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": null,
    "keywords": "sql, database, cli, sqlalchemy, sqlite, postgresql, mysql",
    "author": "Jim Schilling",
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/e7/b2/9fe19eac20e9f65ed2d5a3eb8cfff1695342a92fe7033e391f9b2e74a623/splurge_sql_runner-2025.4.0.tar.gz",
    "platform": null,
    "description": "# splurge-sql-runner\r\nSplurge Python SQL Runner\r\n\r\nA Python utility for executing SQL files against databases with support for multiple statements, comments, and pretty-printed results.\r\n\r\n## Features\r\n\r\n- Execute SQL files with multiple statements\r\n- Support for various database backends (SQLite, PostgreSQL, MySQL, etc.)\r\n- Automatic comment removal and statement parsing\r\n- Pretty-printed results with tabulated output\r\n- Batch processing of multiple files\r\n- Batch SQL execution with error handling\r\n- Clean CLI interface with comprehensive error handling\r\n- Security validation for database URLs and file operations\r\n- Configuration management with JSON-based config files\r\n- Configurable logging for CLI usage (level, format, console/file output)\r\n\r\n## Installation\r\n\r\n```bash\r\npip install splurge-sql-runner\r\n```\r\n\r\n## CLI Usage\r\n\r\nThe main interface is through the command-line tool:\r\n\r\n### Basic Usage\r\n\r\n```bash\r\n# Execute a single SQL file\r\npython -m splurge_sql_runner -c \"sqlite:///database.db\" -f \"script.sql\"\r\n\r\n# Execute multiple SQL files using a pattern\r\npython -m splurge_sql_runner -c \"sqlite:///database.db\" -p \"*.sql\"\r\n\r\n# With verbose output\r\npython -m splurge_sql_runner -c \"sqlite:///database.db\" -f \"script.sql\" -v\r\n\r\n# Using the installed script (after pip install)\r\nsplurge-sql-runner -c \"sqlite:///database.db\" -f \"script.sql\"\r\n\r\n# Load with a JSON config file\r\npython -m splurge_sql_runner --config config.json -c \"sqlite:///database.db\" -f \"script.sql\"\r\n\r\n# Output as JSON (for scripting)\r\npython -m splurge_sql_runner -c \"sqlite:///database.db\" -f \"script.sql\" --json\r\n\r\n# Disable emoji (useful on limited consoles)\r\npython -m splurge_sql_runner -c \"sqlite:///database.db\" -f \"script.sql\" --no-emoji\r\n\r\n# Continue executing statements after an error (per-file)\r\npython -m splurge_sql_runner -c \"sqlite:///database.db\" -f \"script.sql\" --continue-on-error\r\n```\r\n\r\n### Command Line Options\r\n\r\n- `-c, --connection`: Database connection string (required)\r\n  - SQLite: `sqlite:///database.db`\r\n  - PostgreSQL: `postgresql://user:pass@localhost/db`\r\n  - MySQL: `mysql://user:pass@localhost/db`\r\n  \r\n- `-f, --file`: Single SQL file to execute\r\n  \r\n- `-p, --pattern`: File pattern to match multiple SQL files (e.g., \"*.sql\")\r\n  \r\n- `-v, --verbose`: Enable verbose output\r\n  \r\n- `--debug`: Enable SQLAlchemy debug mode (SQLAlchemy echo)\r\n\r\n- `--config FILE`: Path to JSON config file. Values from the file are merged with defaults and overridden\r\n  by any CLI arguments.\r\n\r\n- `--json`: Output results as JSON (machine-readable).\r\n\r\n- `--no-emoji`: Replace emoji glyphs with ASCII tags in output.\r\n\r\n- `--continue-on-error`: Continue processing remaining statements after an error (default is stop on first error).\r\n\r\nSecurity validation cannot be disabled. If stricter defaults block your use case, adjust `SecurityConfig` in your JSON config (e.g., `security.max_statements_per_file`, `security.allowed_file_extensions`, or dangerous pattern lists) and rerun.\r\n\r\n- `--max-statements`: Maximum statements per file (default: 100)\r\n\r\n### Examples\r\n\r\n```bash\r\n# SQLite example\r\npython -m splurge_sql_runner -c \"sqlite:///test.db\" -f \"setup.sql\"\r\n\r\n# PostgreSQL example\r\npython -m splurge_sql_runner -c \"postgresql://user:pass@localhost/mydb\" -p \"migrations/*.sql\"\r\n\r\n# MySQL example with verbose output\r\npython -m splurge_sql_runner -c \"mysql://user:pass@localhost/mydb\" -f \"data.sql\" -v\r\n\r\n# Process all SQL files in current directory\r\npython -m splurge_sql_runner -c \"sqlite:///database.db\" -p \"*.sql\"\r\n\r\n# Adjust security via config (example)\r\n# config.json\r\n#{\r\n#  \"security\": {\r\n#    \"max_statements_per_file\": 500,\r\n#    \"allowed_file_extensions\": [\".sql\", \".ddl\"]\r\n#  }\r\n#}\r\npython -m splurge_sql_runner -c \"sqlite:///database.db\" -f \"script.sql\"\r\n```\r\n\r\n## Security Tuning\r\n\r\nSecurity is enforced by default. If your workflow requires broader allowances, tune these fields in your\r\nJSON configuration file:\r\n\r\n- `security.max_statements_per_file` (int): Maximum SQL statements allowed per file. Increase if you run\r\n  bulk scripts. CLI also accepts `--max-statements` to override per run.\r\n- `security.validation.max_statement_length` (int): Maximum size in characters for a single statement.\r\n- `security.allowed_file_extensions` (list[str]): Allowed extensions for SQL files (e.g., `[\".sql\", \".ddl\"]`).\r\n- `security.validation.dangerous_sql_patterns` (list[str]): Substrings considered dangerous in SQL. Remove\r\n  or modify with caution.\r\n- `security.validation.dangerous_path_patterns` (list[str]): Path substrings that are blocked for file safety.\r\n- `security.validation.dangerous_url_patterns` (list[str]): Connection URL substrings that are blocked.\r\n\r\nExample minimal config to relax limits:\r\n\r\n```json\r\n{\r\n  \"security\": {\r\n    \"max_statements_per_file\": 500,\r\n    \"allowed_file_extensions\": [\".sql\", \".ddl\"],\r\n    \"validation\": {\r\n      \"max_statement_length\": 200000\r\n    }\r\n  }\r\n}\r\n```\r\n\r\n## Logging Behavior\r\n\r\nLogging is configured via the `logging` section in your JSON config and is applied automatically on startup:\r\n\r\n- `logging.level`: One of `DEBUG`, `INFO`, `WARNING`, `ERROR`, `CRITICAL`.\r\n- `logging.format`: `TEXT` (human-readable) or `JSON`.\r\n- `logging.enable_console`: Whether to log to console.\r\n- `logging.enable_file`: Whether to log to a file.\r\n- `logging.log_file`/`logging.log_dir`: Exact file or directory to write logs. If only `log_dir` is provided, a default filename is used.\r\n- `logging.backup_count`: Number of daily-rotated log files to keep.\r\n\r\nCLI will bootstrap minimal logging with default values and then reconfigure using your JSON config (if provided) before running.\r\n\r\n## Notes on paths and patterns\r\n\r\n- The `--file` path is expanded with `~` (home) and resolved to an absolute path before use.\r\n- The `--pattern` is expanded for `~` and matched with glob; matched files are resolved to absolute paths.\r\n\r\n## Programmatic Usage\r\n\r\n**Note**: This library is primarily designed to be used via the CLI interface. The programmatic API is provided for advanced use cases and integration scenarios, but the CLI offers the most comprehensive features and best user experience.\r\n\r\n### Basic Usage\r\n\r\n```python\r\nfrom splurge_sql_runner.database.database_client import DatabaseClient\r\nfrom splurge_sql_runner.config.database_config import DatabaseConfig\r\n\r\nclient = DatabaseClient(DatabaseConfig(url=\"sqlite:///database.db\"))\r\n\r\ntry:\r\n    results = client.execute_batch(\"SELECT 1;\")\r\n    for r in results:\r\n        print(r)\r\nfinally:\r\n    client.close()\r\n```\r\n\r\n### Advanced Usage\r\n\r\n```python\r\nfrom splurge_sql_runner.config import AppConfig\r\nfrom splurge_sql_runner.database import DatabaseClient\r\n\r\nconfig = AppConfig.load(\"config.json\")\r\n\r\nclient = DatabaseClient(config.database)\r\n\r\ntry:\r\n    results = client.execute_batch(\"SELECT 1; INSERT INTO test VALUES (1);\")\r\n    for result in results:\r\n        print(f\"Statement type: {result['statement_type']}\")\r\n        if result['statement_type'] == 'fetch':\r\n            print(f\"Rows returned: {result['row_count']}\")\r\nfinally:\r\n    client.close()\r\n```\r\n\r\n\r\n\r\n## Configuration\r\n\r\nThe library supports JSON-based configuration files for advanced usage:\r\n\r\n```json\r\n{\r\n    \"database\": {\r\n        \"url\": \"sqlite:///database.db\",\r\n        \"connection\": {\r\n            \"timeout\": 30\r\n        },\r\n        \"enable_debug\": false\r\n    },\r\n    \"security\": {\r\n        \"enable_validation\": true,\r\n        \"max_statements_per_file\": 100\r\n    },\r\n    \"logging\": {\r\n        \"level\": \"INFO\",\r\n        \"format\": \"TEXT\",\r\n        \"enable_console\": true,\r\n        \"enable_file\": false\r\n    }\r\n}\r\n```\r\n\r\n## SQL File Format\r\n\r\nThe tool supports SQL files with:\r\n- Multiple statements separated by semicolons\r\n- Single-line comments (`-- comment`)\r\n- Multi-line comments (`/* comment */`)\r\n- Comments within string literals are preserved\r\n\r\nExample SQL file:\r\n```sql\r\n-- Create table\r\nCREATE TABLE users (\r\n    id INTEGER PRIMARY KEY,\r\n    name TEXT NOT NULL\r\n);\r\n\r\n-- Insert data\r\nINSERT INTO users (name) VALUES ('John');\r\nINSERT INTO users (name) VALUES ('Jane');\r\n\r\n-- Query data\r\nSELECT * FROM users;\r\n```\r\n\r\n## Output Format\r\n\r\nThe CLI provides formatted output showing:\r\n- File being processed\r\n- Each statement executed\r\n- Results in tabulated format for SELECT queries\r\n- Success/error status for each statement\r\n- Summary of files processed\r\n\r\n## Error Handling\r\n\r\n- Individual statement errors don't stop the entire batch\r\n- Failed statements are reported with error details\r\n- Database connections are properly cleaned up\r\n- Exit codes indicate success/failure\r\n- (Removed) Circuit breaker/retry error-recovery layers in favor of simple CLI errors\r\n- Security validation with configurable thresholds\r\n\r\n## License\r\n\r\nMIT License - see LICENSE file for details.\r\n\r\n## Development\r\n\r\n### Installation for Development\r\n\r\n```bash\r\n# Clone the repository\r\ngit clone https://github.com/jim-schilling/splurge-sql-runner.git\r\ncd splurge-sql-runner\r\n\r\n# Install in development mode with all dependencies\r\npip install -e \".[dev]\"\r\n\r\n# Run tests\r\npytest -x -v\r\n\r\n# Run linting\r\nflake8 splurge_sql_runner/\r\nblack splurge_sql_runner/\r\nmypy splurge_sql_runner/\r\n```\r\n\r\n## Changelog\r\n\r\n### 2025.4.0 (08-24-2025)\r\n\r\n- **Performance & Code Quality**: Optimized and simplified `sql_helper.py` module\r\n  - **Reduced complexity**: Eliminated 5 helper functions and consolidated keyword sets\r\n  - **Better performance**: Implemented O(1) set membership checks and unified CTE scanner\r\n  - **Cleaner code**: Single token normalization and simplified control flow\r\n  - **Accurate documentation**: Removed misleading caching claims from docstrings\r\n  - **Reduced maintenance burden**: Removed unused `ERROR_STATEMENT` constant and helpers\r\n  - **Bug fix**: Enhanced comment filtering in `parse_sql_statements` for edge cases\r\n- **Backward Compatibility**: All public APIs remain unchanged, no breaking changes\r\n- **Test Coverage**: Maintained 93% test coverage with all existing functionality preserved\r\n- **Documentation**: Created comprehensive optimization plan in `plans/sql_helper_optimization_plan.md`\r\n- **Verification**: All examples and tests continue to work correctly after optimization\r\n\r\n### 2025.3.1 (08-20-2025)\r\n\r\n- **Test Coverage**: Improved test coverage to 85% target across core modules\r\n  - `sql_helper.py`: Reached 85% coverage with comprehensive edge case testing\r\n  - `database_client.py`: Improved from ~71% to 77% coverage with additional test scenarios\r\n  - `cli.py`: Reached 84% coverage with enhanced CLI functionality testing\r\n- **Test Quality**: Added behavior-driven tests focusing on public APIs and real functionality\r\n  - Enhanced CTE (Common Table Expressions) parsing edge cases\r\n  - Added DCL (Data Control Language) statement type detection\r\n  - Improved error handling and rollback behavior testing\r\n  - Added config file handling and security guidance output tests\r\n  - Enhanced pattern matching and multi-file processing scenarios\r\n- **Code Quality**: Moved all import statements to top of modules where possible\r\n  - Cleaned up inline imports in test files (`test_cli.py`, `conftest.py`, `test_logging_performance.py`)\r\n  - Removed duplicate test functions that were accidentally created\r\n  - Maintained appropriate inline imports for test setup methods where needed\r\n- **Documentation**: Created comprehensive test improvement plan in `plans/improve-code-coverage.md`\r\n- **Testing**: Verified all examples work correctly with enhanced test suite\r\n  - Interactive demo functionality confirmed working\r\n  - CLI automation tests passing\r\n  - Database deployment script execution verified\r\n  - Pattern matching and JSON output features tested\r\n\r\n### 2025.3.0 (08-11-2025)\r\n\r\n- **Documentation**: Updated Programmatic Usage section to clarify that the library is primarily designed for CLI usage\r\n- **Documentation**: Added note explaining that programmatic API is for advanced use cases and integration scenarios\r\n- **Documentation**: Emphasized that CLI offers the most comprehensive features and best user experience\r\n- **Breaking Changes**: Unified engine abstraction replaced by `DatabaseClient`\r\n- **New**: Centralized configuration constants in `splurge_sql_runner.config.constants`\r\n- **Improved**: Security validation now uses centralized `SecurityConfig` from `splurge_sql_runner.config.security_config`\r\n- **Code Quality**: Eliminated code duplication across the codebase\r\n- **Breaking Changes**: Environment variables now use `SPLURGE_SQL_RUNNER_` prefix instead of `JPY_`\r\n  - `JPY_DB_URL` \u2192 `SPLURGE_SQL_RUNNER_DB_URL`\r\n  - `JPY_DB_TIMEOUT` \u2192 `SPLURGE_SQL_RUNNER_DB_TIMEOUT`\r\n  - `JPY_SECURITY_ENABLED` \u2192 `SPLURGE_SQL_RUNNER_SECURITY_ENABLED`\r\n  - `JPY_MAX_FILE_SIZE_MB` \u2192 `SPLURGE_SQL_RUNNER_MAX_FILE_SIZE_MB`\r\n  - `JPY_MAX_STATEMENTS_PER_FILE` \u2192 `SPLURGE_SQL_RUNNER_MAX_STATEMENTS_PER_FILE`\r\n  - `JPY_VERBOSE` \u2192 `SPLURGE_SQL_RUNNER_VERBOSE`\r\n  - `JPY_LOG_LEVEL` \u2192 `SPLURGE_SQL_RUNNER_LOG_LEVEL`\r\n  - `JPY_LOG_FORMAT` \u2192 `SPLURGE_SQL_RUNNER_LOG_FORMAT`\r\n\r\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "A Python utility for executing SQL files against databases with support for multiple statements, comments, and pretty-printed results",
    "version": "2025.4.0",
    "project_urls": {
        "Changelog": "https://github.com/jim-schilling/splurge-sql-runner/blob/main/README.md#changelog",
        "Documentation": "https://github.com/jim-schilling/splurge-sql-runner#readme",
        "Homepage": "https://github.com/jim-schilling/splurge-sql-runner",
        "Issues": "https://github.com/jim-schilling/splurge-sql-runner/issues",
        "Repository": "https://github.com/jim-schilling/splurge-sql-runner.git"
    },
    "split_keywords": [
        "sql",
        " database",
        " cli",
        " sqlalchemy",
        " sqlite",
        " postgresql",
        " mysql"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "9c2c2999904bd0e4bbdd363c129b46e59dc2f3497aa0dc69f9efd18770a4e762",
                "md5": "01676e13d77da1366e69ca694e02f5a4",
                "sha256": "0b3f0806d9ece581d914b1126b677d462b8e82e130fc804499e808a8e5a06356"
            },
            "downloads": -1,
            "filename": "splurge_sql_runner-2025.4.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "01676e13d77da1366e69ca694e02f5a4",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10",
            "size": 45399,
            "upload_time": "2025-08-24T21:42:15",
            "upload_time_iso_8601": "2025-08-24T21:42:15.020457Z",
            "url": "https://files.pythonhosted.org/packages/9c/2c/2999904bd0e4bbdd363c129b46e59dc2f3497aa0dc69f9efd18770a4e762/splurge_sql_runner-2025.4.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "e7b29fe19eac20e9f65ed2d5a3eb8cfff1695342a92fe7033e391f9b2e74a623",
                "md5": "c1c0243d8bf8b77740eeeadefe49c5a0",
                "sha256": "a8cd48495da1d26f75c5a4a5d4a65ec157a5f200962f178bb7be5ba6b82aa4a2"
            },
            "downloads": -1,
            "filename": "splurge_sql_runner-2025.4.0.tar.gz",
            "has_sig": false,
            "md5_digest": "c1c0243d8bf8b77740eeeadefe49c5a0",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 70881,
            "upload_time": "2025-08-24T21:42:16",
            "upload_time_iso_8601": "2025-08-24T21:42:16.269042Z",
            "url": "https://files.pythonhosted.org/packages/e7/b2/9fe19eac20e9f65ed2d5a3eb8cfff1695342a92fe7033e391f9b2e74a623/splurge_sql_runner-2025.4.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-08-24 21:42:16",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "jim-schilling",
    "github_project": "splurge-sql-runner",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "splurge-sql-runner"
}
        
Elapsed time: 0.96765s