# splurge-sql-generator
A Python library for generating SQLAlchemy classes from SQL template files with sophisticated SQL parsing and statement type detection.
## Features
- **SQL Template Parsing**: Parse SQL files with method name comments to extract queries
- **Statement Type Detection**: Automatically detect if SQL statements return rows (fetch) or perform operations (execute)
- **Code Generation**: Generate Python classes with SQLAlchemy methods
- **Parameter Extraction**: Extract and map SQL parameters to Python method signatures
- **CLI Interface**: Command-line tool for batch processing
- **Comprehensive Error Handling**: Robust error handling for file operations and SQL parsing
## SQL File Format Requirement
> **Important:** The first line of every SQL file must be a class comment specifying the class name, e.g.:
>
> # UserRepository
>
> This class name will be used for the generated Python class. The filename is no longer used for class naming.
## Installation
```bash
pip install splurge-sql-generator
```
Or install from source:
```bash
git clone https://github.com/yourusername/splurge-sql-generator.git
cd splurge-sql-generator
pip install -e .
```
## Quick Start
### 1. Create a SQL Template File
Create a file named `UserRepository.sql`:
```sql
# UserRepository
#get_user_by_id
SELECT id, username, email, created_at
FROM users
WHERE id = :user_id;
#create_user
INSERT INTO users (username, email, password_hash, status)
VALUES (:username, :email, :password_hash, :status)
RETURNING id;
#update_user_status
UPDATE users
SET status = :new_status, updated_at = CURRENT_TIMESTAMP
WHERE id = :user_id;
```
### 2. Generate Python Class
Using the CLI:
```bash
# Module invocation
python -m splurge_sql_generator.cli UserRepository.sql --output generated/
# Or via the installed console script
splurge-sql-gen UserRepository.sql --output generated/
```
Or using Python:
```python
from splurge_sql_generator import PythonCodeGenerator, generate_class
generator = PythonCodeGenerator()
code = generator.generate_class(
'UserRepository.sql',
output_file_path='generated/UserRepository.py',
)
# Or use the convenience function
code2 = generate_class(
'UserRepository.sql',
output_file_path='generated/UserRepository.py',
)
```
### 3. Use the Generated Class
```python
from sqlalchemy import create_engine
from generated.UserRepository import UserRepository
# Create database connection
engine = create_engine('sqlite:///example.db')
connection = engine.connect()
# Use the generated class methods (class methods only)
users = UserRepository.get_user_by_id(
connection=connection,
user_id=1,
)
# For data modification operations, use transaction blocks
with connection.begin():
result = UserRepository.create_user(
connection=connection,
username='john_doe',
email='john@example.com',
password_hash='hashed_password',
status='active',
)
# Transaction commits automatically when context exits
# For multiple operations in a single transaction:
with connection.begin():
UserRepository.create_user(
connection=connection,
username='jane',
email='jane@example.com',
password_hash='pw',
status='active',
)
UserRepository.update_user_status(
connection=connection,
user_id=1,
new_status='active',
)
# All operations commit together, or all rollback on error
# Note: All generated methods now use a class-level logger automatically. There is no optional logger parameter. To customize logging, configure the class logger as needed:
# import logging
# UserRepository.logger.setLevel(logging.INFO)
```
> **Note:** All generated methods are class methods. You must always pass the connection and parameters as named arguments. **For data modification operations (INSERT, UPDATE, DELETE), use `with connection.begin():` blocks to manage transactions explicitly.** This gives you full control over transaction boundaries and ensures data consistency.
## Usage Examples
### Statement Type Detection
```python
from splurge_sql_generator import detect_statement_type, is_fetch_statement
# Detect statement types
sql1 = "SELECT * FROM users WHERE id = :user_id"
print(detect_statement_type(sql1)) # 'fetch'
sql2 = "INSERT INTO users (name) VALUES (:name)"
print(detect_statement_type(sql2)) # 'execute'
# Convenience functions
print(is_fetch_statement(sql1)) # True
print(is_fetch_statement(sql2)) # False
```
### Complex SQL with CTEs
```sql
# UserStats
#get_user_stats
WITH user_orders AS (
SELECT user_id, COUNT(*) as order_count
FROM orders
GROUP BY user_id
)
SELECT u.name, uo.order_count
FROM users u
LEFT JOIN user_orders uo ON u.id = uo.user_id
WHERE u.id = :user_id AND u.status = :status;
```
The generator will correctly detect this as a fetch statement and generate appropriate Python code.
### CLI Usage
```bash
# Generate single class (module)
python -m splurge_sql_generator.cli UserRepository.sql --output generated/
# Generate single class (console script)
splurge-sql-gen UserRepository.sql --output generated/
# Generate multiple classes (globs expanded by shell)
splurge-sql-gen *.sql --output generated/
# Generate from a directory recursively
splurge-sql-gen path/to/sqls/ --output generated/
# Preview generated code without saving
splurge-sql-gen UserRepository.sql --dry-run
# Strict mode: treat warnings (e.g., non-.sql inputs, empty dir) as errors
splurge-sql-gen path/to/sqls/ --output generated/ --strict
# Generate to specific output directory
splurge-sql-gen UserRepository.sql -o src/repositories/
```
## API Reference
### Core Classes
#### `PythonCodeGenerator`
Main class for generating Python code from SQL templates.
```python
generator = PythonCodeGenerator()
code = generator.generate_class(sql_file_path, output_file_path=None)
classes = generator.generate_multiple_classes(sql_files, output_dir=None)
```
#### `SqlParser`
Parser for SQL template files.
```python
parser = SqlParser()
class_name, method_queries = parser.parse_file(sql_file_path)
method_info = parser.get_method_info(sql_query)
```
### SQL Helper Functions
#### `detect_statement_type(sql: str) -> str`
Detect if a SQL statement returns rows ('fetch') or performs operations ('execute').
#### `is_fetch_statement(sql: str) -> bool`
Convenience function to check if a statement returns rows.
#### `is_execute_statement(sql: str) -> bool`
Convenience function to check if a statement performs operations.
#### `remove_sql_comments(sql_text: str) -> str`
Remove SQL comments from a SQL string.
#### `parse_sql_statements(sql_text: str, strip_semicolon: bool = False) -> List[str]`
Parse a SQL string containing multiple statements into individual statements.
#### `split_sql_file(file_path: str, strip_semicolon: bool = False) -> List[str]`
Read a SQL file and split it into individual statements.
## Supported SQL Features
- **Basic DML**: SELECT, INSERT, UPDATE, DELETE
- **CTEs**: Common Table Expressions (WITH clauses)
- **Complex Queries**: Subqueries, JOINs, aggregations
- **Database-Specific**: SHOW, EXPLAIN, DESCRIBE, VALUES
- **Parameters**: Named parameters with `:param_name` syntax
- **Comments**: Single-line (`--`) and multi-line (`/* */`) comments
## Generated Code Features
- **Type Hints**: Full type annotations for parameters and return values
- **Docstrings**: Comprehensive documentation for each method
- **Error Handling**: Proper SQLAlchemy result handling
- **Parameter Mapping**: Automatic mapping of SQL parameters to Python arguments
- **Statement Type Detection**: Correct return types based on SQL statement type
- **Auto-Generated Headers**: Clear identification of generated files
## Development
### Running Tests
```bash
python -m unittest discover -s tests -v
```
### Project Structure
```
splurge-sql-generator/
├── splurge_sql_generator/
│ ├── __init__.py # Main package exports
│ ├── sql_helper.py # SQL parsing utilities
│ ├── sql_parser.py # SQL template parser
│ ├── code_generator.py # Python code generator
│ ├── cli.py # Command-line interface
│ └── templates/ # Jinja2 templates (python_class.j2)
├── tests/ # Test suite
├── examples/ # Example SQL templates
└── output/ # Generated code examples
```
## License
MIT License - see LICENSE file for details.
## Contributing
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests for new functionality
5. Run the test suite
6. Submit a pull request
---
## Changelog
### [2025.3.0] - 2025-08-13
#### Changed
- Package renamed and unified under `splurge-sql-generator` / `splurge_sql_generator`
- Keyword-only, fully typed public APIs (Python 3.10+ unions, precise return types)
- CLI improvements: directory input recursion and `--strict` mode
- Narrowed public exports to user-facing helpers and classes
- Consistent exceptions: `SqlValidationError` for validation; now inherits from `ValueError`
- Generated classes add a `NullHandler` to the class logger to avoid warnings
- Faster generation: preloaded Jinja template and single-parse batch generation
- Documentation updates and examples migrated to new package/module names
> Note: Backwards-compatibility with positional arguments was intentionally removed. Use keyword-only parameters (`output_file_path=...`, `output_dir=...`).
### [0.2.4] - 2025-06-30
#### Changed
- **Strict Python identifier enforcement**: Method names, class names, and parameter names extracted from SQL templates must now be valid Python identifiers. Invalid names will raise errors during code generation.
- **Improved error messages**: Clearer error reporting when invalid names are detected in SQL templates.
- **Documentation update**: The requirement for valid Python names is now explicitly documented in the README and enforced in the code generator.
> **Note:** All method names, class names, and parameter names in your SQL templates must be valid Python identifiers (letters, numbers, and underscores, not starting with a number, and not a Python keyword). This ensures the generated code is always valid and importable.
### [0.2.3] - 2025-06-29
#### Changed
- **Updated pyproject.toml**: Modernized build configuration with current best practices and comprehensive metadata
- **Enhanced development setup**: Added optional dependency groups for dev, test, and docs tools
- **Improved package metadata**: Added keywords, comprehensive classifiers, and better project description
- **Type safety improvements**: Fixed all mypy type checking issues throughout the codebase
- **Enhanced test coverage**: Added comprehensive test cases to achieve 81% overall coverage
#### Technical Improvements
- **Modern build system**: Upgraded to setuptools 68.0+ for better compatibility
- **Development dependencies**: Added pytest, black, isort, flake8, mypy, and sphinx for development workflow
- **Type annotations**: Added missing return type annotations and fixed type compatibility issues
- **Code quality tools**: Integrated Black (formatter), isort (import sorter), flake8 (linter), and mypy (type checker)
- **Comprehensive testing**: Added tests for CLI error handling, edge cases, and public API coverage
- **Cross-platform compatibility**: Ensured all tests work reliably on Windows and Unix systems
#### Development Experience
- **One-command setup**: `pip install -e ".[dev]"` installs all development tools
- **Automated code formatting**: Black and isort ensure consistent code style
- **Static analysis**: flake8 and mypy provide comprehensive code quality checks
- **Test automation**: pytest with coverage reporting for quality assurance
- **Documentation support**: Sphinx integration for generating project documentation
### [0.2.2] - 2025-06-29
#### Changed
- **Simplified logger handling**: Removed optional `logger` parameter from all generated methods to always use class-level logger
- **Cleaner API**: Reduced parameter clutter by eliminating the optional logger parameter
- **Consistent logging**: All methods now use the same class-level logger for uniform logging behavior
- **Updated test suite**: Modified tests to reflect the simplified logger approach
#### Technical Improvements
- **Simplified method signatures**: Generated methods now have fewer parameters and cleaner interfaces
- **Consistent logging pattern**: Class-level logger approach follows common Python utility class patterns
- **Reduced complexity**: Eliminated conditional logger assignment logic in generated code
- **Better maintainability**: Generated code is simpler and easier to understand
### [0.2.1] - 2025-06-29
#### Changed
- **Refactored `sql_helper.py`**: Improved error handling and input validation for file operations.
- **Stricter type checks**: Functions now validate input types and raise clear exceptions for invalid arguments.
- **Robust SQL parsing utilities**: Enhanced parsing and comment removal logic for more accurate statement detection and splitting.
- **Improved documentation**: Expanded and clarified docstrings for all helper functions.
### [0.2.0] - 2025-06-28
#### Changed
- **Switched to class-methods-only approach**: Removed instance methods and constructors for better transaction control
- **Removed automatic commit/rollback**: Data modification operations no longer automatically commit or rollback, allowing explicit transaction management
- **Added comprehensive logging**: All operations now include debug and error logging with customizable logger support
- **Improved parameter formatting**: All method parameters are now on separate lines with proper PEP8 formatting
- **Enhanced error handling**: Simplified exception handling without automatic rollback interference
#### Technical Improvements
- **Explicit transaction control**: Users must use `with connection.begin():` blocks for data modifications
- **Better encapsulation**: No shared state between method calls, improving thread safety
- **Named parameters required**: All methods use `*` to force named parameter usage for clarity
- **Class-level logger**: Default logger with optional override per method call
- **Production-ready**: Generated code is now suitable for production use with proper transaction management
#### Generated Code Enhancements
- **Transaction safety**: No automatic commits that could interfere with user-managed transactions
- **Cleaner API**: Class methods only, no instance state to manage
- **Better error propagation**: Exceptions are logged but not automatically rolled back
- **Maintained API compatibility**: Public API remains consistent while improving safety
### [0.1.1] - 2025-06-28
#### Changed
- **Refactored code generator to use Jinja2 templates**: Replaced string concatenation with template-based code generation for better maintainability and flexibility
- **Added Jinja2 dependency**: Added `jinja2>=3.1.0` to requirements.txt
- **Created templates directory**: Added `splurge_sql_generator/templates/` with `python_class.j2` template
- **Simplified code generation logic**: Removed individual method generation functions in favor of template rendering
- **Updated test suite**: Modified tests to work with new template-based approach while maintaining full functionality
#### Technical Improvements
- **Template-based generation**: All Python code is now generated using Jinja2 templates, making it easier to modify output format
- **Better separation of concerns**: Template logic is separated from Python generation logic
- **Maintained API compatibility**: Public API remains unchanged, ensuring backward compatibility
- **Enhanced maintainability**: Code generation format can now be modified by editing templates without touching Python logic
### [0.1.0] - 2025-06-28
#### Added
- Initial release of splurge-sql-generator
- SQL template parsing with method name extraction
- Sophisticated SQL statement type detection (fetch vs execute)
- Support for Common Table Expressions (CTEs)
- Python code generation with SQLAlchemy integration
- Command-line interface for batch processing
- Comprehensive parameter extraction and mapping
- Support for complex SQL features (subqueries, JOINs, aggregations)
- Auto-generated file headers with tool attribution
- Robust error handling for file operations
- Comprehensive test suite with edge case coverage
#### Features
- **SQL Helper Utilities**: `detect_statement_type()`, `remove_sql_comments()`, `parse_sql_statements()`
- **Template Parser**: Extract method names and SQL queries from template files
- **Code Generator**: Generate Python classes with proper type hints and docstrings
- **CLI Tool**: Command-line interface with dry-run and batch processing options
- **Statement Detection**: Automatic detection of fetch vs execute statements
- **Parameter Handling**: Deduplication and proper mapping of SQL parameters
#### Technical Details
- Uses `sqlparse` for robust SQL parsing
- Supports all major SQL statement types
- Generates Python code with SQLAlchemy best practices
- Comprehensive error handling and validation
- MIT licensed with clear copyright attribution
Raw data
{
"_id": null,
"home_page": null,
"name": "splurge-sql-generator",
"maintainer": "Jim Schilling",
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": "sql, code-generation, python, sqlalchemy, jinja2",
"author": "Jim Schilling",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/7d/66/5da3c5af20846e441056b813a5edfc62b810bdf0d5a55c574f7caf9ad3c0/splurge_sql_generator-2025.3.0.tar.gz",
"platform": null,
"description": "# splurge-sql-generator\r\n\r\nA Python library for generating SQLAlchemy classes from SQL template files with sophisticated SQL parsing and statement type detection.\r\n\r\n## Features\r\n\r\n- **SQL Template Parsing**: Parse SQL files with method name comments to extract queries\r\n- **Statement Type Detection**: Automatically detect if SQL statements return rows (fetch) or perform operations (execute)\r\n- **Code Generation**: Generate Python classes with SQLAlchemy methods\r\n- **Parameter Extraction**: Extract and map SQL parameters to Python method signatures\r\n- **CLI Interface**: Command-line tool for batch processing\r\n- **Comprehensive Error Handling**: Robust error handling for file operations and SQL parsing\r\n\r\n## SQL File Format Requirement\r\n\r\n> **Important:** The first line of every SQL file must be a class comment specifying the class name, e.g.:\r\n>\r\n> # UserRepository\r\n>\r\n> This class name will be used for the generated Python class. The filename is no longer used for class naming.\r\n\r\n## Installation\r\n\r\n```bash\r\npip install splurge-sql-generator\r\n```\r\n\r\nOr install from source:\r\n\r\n```bash\r\ngit clone https://github.com/yourusername/splurge-sql-generator.git\r\ncd splurge-sql-generator\r\npip install -e .\r\n```\r\n\r\n## Quick Start\r\n\r\n### 1. Create a SQL Template File\r\n\r\nCreate a file named `UserRepository.sql`:\r\n\r\n```sql\r\n# UserRepository\r\n#get_user_by_id\r\nSELECT id, username, email, created_at \r\nFROM users \r\nWHERE id = :user_id;\r\n\r\n#create_user\r\nINSERT INTO users (username, email, password_hash, status) \r\nVALUES (:username, :email, :password_hash, :status) \r\nRETURNING id;\r\n\r\n#update_user_status\r\nUPDATE users \r\nSET status = :new_status, updated_at = CURRENT_TIMESTAMP \r\nWHERE id = :user_id;\r\n```\r\n\r\n### 2. Generate Python Class\r\n\r\nUsing the CLI:\r\n\r\n```bash\r\n# Module invocation\r\npython -m splurge_sql_generator.cli UserRepository.sql --output generated/\r\n\r\n# Or via the installed console script\r\nsplurge-sql-gen UserRepository.sql --output generated/\r\n```\r\n\r\nOr using Python:\r\n\r\n```python\r\nfrom splurge_sql_generator import PythonCodeGenerator, generate_class\r\n\r\ngenerator = PythonCodeGenerator()\r\ncode = generator.generate_class(\r\n 'UserRepository.sql',\r\n output_file_path='generated/UserRepository.py',\r\n)\r\n\r\n# Or use the convenience function\r\ncode2 = generate_class(\r\n 'UserRepository.sql',\r\n output_file_path='generated/UserRepository.py',\r\n)\r\n```\r\n\r\n### 3. Use the Generated Class\r\n\r\n```python\r\nfrom sqlalchemy import create_engine\r\nfrom generated.UserRepository import UserRepository\r\n\r\n# Create database connection\r\nengine = create_engine('sqlite:///example.db')\r\nconnection = engine.connect()\r\n\r\n# Use the generated class methods (class methods only)\r\nusers = UserRepository.get_user_by_id(\r\n connection=connection,\r\n user_id=1,\r\n)\r\n\r\n# For data modification operations, use transaction blocks\r\nwith connection.begin():\r\n result = UserRepository.create_user(\r\n connection=connection,\r\n username='john_doe',\r\n email='john@example.com',\r\n password_hash='hashed_password',\r\n status='active',\r\n )\r\n # Transaction commits automatically when context exits\r\n\r\n# For multiple operations in a single transaction:\r\nwith connection.begin():\r\n UserRepository.create_user(\r\n connection=connection,\r\n username='jane',\r\n email='jane@example.com',\r\n password_hash='pw',\r\n status='active',\r\n )\r\n UserRepository.update_user_status(\r\n connection=connection,\r\n user_id=1,\r\n new_status='active',\r\n )\r\n # All operations commit together, or all rollback on error\r\n\r\n# Note: All generated methods now use a class-level logger automatically. There is no optional logger parameter. To customize logging, configure the class logger as needed:\r\n# import logging\r\n# UserRepository.logger.setLevel(logging.INFO)\r\n```\r\n\r\n> **Note:** All generated methods are class methods. You must always pass the connection and parameters as named arguments. **For data modification operations (INSERT, UPDATE, DELETE), use `with connection.begin():` blocks to manage transactions explicitly.** This gives you full control over transaction boundaries and ensures data consistency.\r\n\r\n## Usage Examples\r\n\r\n### Statement Type Detection\r\n\r\n```python\r\nfrom splurge_sql_generator import detect_statement_type, is_fetch_statement\r\n\r\n# Detect statement types\r\nsql1 = \"SELECT * FROM users WHERE id = :user_id\"\r\nprint(detect_statement_type(sql1)) # 'fetch'\r\n\r\nsql2 = \"INSERT INTO users (name) VALUES (:name)\"\r\nprint(detect_statement_type(sql2)) # 'execute'\r\n\r\n# Convenience functions\r\nprint(is_fetch_statement(sql1)) # True\r\nprint(is_fetch_statement(sql2)) # False\r\n```\r\n\r\n### Complex SQL with CTEs\r\n\r\n```sql\r\n# UserStats\r\n#get_user_stats\r\nWITH user_orders AS (\r\n SELECT user_id, COUNT(*) as order_count\r\n FROM orders\r\n GROUP BY user_id\r\n)\r\nSELECT u.name, uo.order_count\r\nFROM users u\r\nLEFT JOIN user_orders uo ON u.id = uo.user_id\r\nWHERE u.id = :user_id AND u.status = :status;\r\n```\r\n\r\nThe generator will correctly detect this as a fetch statement and generate appropriate Python code.\r\n\r\n### CLI Usage\r\n\r\n```bash\r\n# Generate single class (module)\r\npython -m splurge_sql_generator.cli UserRepository.sql --output generated/\r\n\r\n# Generate single class (console script)\r\nsplurge-sql-gen UserRepository.sql --output generated/\r\n\r\n# Generate multiple classes (globs expanded by shell)\r\nsplurge-sql-gen *.sql --output generated/\r\n\r\n# Generate from a directory recursively\r\nsplurge-sql-gen path/to/sqls/ --output generated/\r\n\r\n# Preview generated code without saving\r\nsplurge-sql-gen UserRepository.sql --dry-run\r\n\r\n# Strict mode: treat warnings (e.g., non-.sql inputs, empty dir) as errors\r\nsplurge-sql-gen path/to/sqls/ --output generated/ --strict\r\n\r\n# Generate to specific output directory\r\nsplurge-sql-gen UserRepository.sql -o src/repositories/\r\n```\r\n\r\n## API Reference\r\n\r\n### Core Classes\r\n\r\n#### `PythonCodeGenerator`\r\nMain class for generating Python code from SQL templates.\r\n\r\n```python\r\ngenerator = PythonCodeGenerator()\r\ncode = generator.generate_class(sql_file_path, output_file_path=None)\r\nclasses = generator.generate_multiple_classes(sql_files, output_dir=None)\r\n```\r\n\r\n#### `SqlParser`\r\nParser for SQL template files.\r\n\r\n```python\r\nparser = SqlParser()\r\nclass_name, method_queries = parser.parse_file(sql_file_path)\r\nmethod_info = parser.get_method_info(sql_query)\r\n```\r\n\r\n### SQL Helper Functions\r\n\r\n#### `detect_statement_type(sql: str) -> str`\r\nDetect if a SQL statement returns rows ('fetch') or performs operations ('execute').\r\n\r\n#### `is_fetch_statement(sql: str) -> bool`\r\nConvenience function to check if a statement returns rows.\r\n\r\n#### `is_execute_statement(sql: str) -> bool`\r\nConvenience function to check if a statement performs operations.\r\n\r\n#### `remove_sql_comments(sql_text: str) -> str`\r\nRemove SQL comments from a SQL string.\r\n\r\n#### `parse_sql_statements(sql_text: str, strip_semicolon: bool = False) -> List[str]`\r\nParse a SQL string containing multiple statements into individual statements.\r\n\r\n#### `split_sql_file(file_path: str, strip_semicolon: bool = False) -> List[str]`\r\nRead a SQL file and split it into individual statements.\r\n\r\n## Supported SQL Features\r\n\r\n- **Basic DML**: SELECT, INSERT, UPDATE, DELETE\r\n- **CTEs**: Common Table Expressions (WITH clauses)\r\n- **Complex Queries**: Subqueries, JOINs, aggregations\r\n- **Database-Specific**: SHOW, EXPLAIN, DESCRIBE, VALUES\r\n- **Parameters**: Named parameters with `:param_name` syntax\r\n- **Comments**: Single-line (`--`) and multi-line (`/* */`) comments\r\n\r\n## Generated Code Features\r\n\r\n- **Type Hints**: Full type annotations for parameters and return values\r\n- **Docstrings**: Comprehensive documentation for each method\r\n- **Error Handling**: Proper SQLAlchemy result handling\r\n- **Parameter Mapping**: Automatic mapping of SQL parameters to Python arguments\r\n- **Statement Type Detection**: Correct return types based on SQL statement type\r\n- **Auto-Generated Headers**: Clear identification of generated files\r\n\r\n## Development\r\n\r\n### Running Tests\r\n\r\n```bash\r\npython -m unittest discover -s tests -v\r\n```\r\n\r\n### Project Structure\r\n\r\n```\r\nsplurge-sql-generator/\r\n\u251c\u2500\u2500 splurge_sql_generator/\r\n\u2502 \u251c\u2500\u2500 __init__.py # Main package exports\r\n\u2502 \u251c\u2500\u2500 sql_helper.py # SQL parsing utilities\r\n\u2502 \u251c\u2500\u2500 sql_parser.py # SQL template parser\r\n\u2502 \u251c\u2500\u2500 code_generator.py # Python code generator\r\n\u2502 \u251c\u2500\u2500 cli.py # Command-line interface\r\n\u2502 \u2514\u2500\u2500 templates/ # Jinja2 templates (python_class.j2)\r\n\u251c\u2500\u2500 tests/ # Test suite\r\n\u251c\u2500\u2500 examples/ # Example SQL templates\r\n\u2514\u2500\u2500 output/ # Generated code examples\r\n```\r\n\r\n## License\r\n\r\nMIT License - see LICENSE file for details.\r\n\r\n## Contributing\r\n\r\n1. Fork the repository\r\n2. Create a feature branch\r\n3. Make your changes\r\n4. Add tests for new functionality\r\n5. Run the test suite\r\n6. Submit a pull request\r\n\r\n---\r\n\r\n## Changelog\r\n\r\n### [2025.3.0] - 2025-08-13\r\n\r\n#### Changed\r\n- Package renamed and unified under `splurge-sql-generator` / `splurge_sql_generator`\r\n- Keyword-only, fully typed public APIs (Python 3.10+ unions, precise return types)\r\n- CLI improvements: directory input recursion and `--strict` mode\r\n- Narrowed public exports to user-facing helpers and classes\r\n- Consistent exceptions: `SqlValidationError` for validation; now inherits from `ValueError`\r\n- Generated classes add a `NullHandler` to the class logger to avoid warnings\r\n- Faster generation: preloaded Jinja template and single-parse batch generation\r\n- Documentation updates and examples migrated to new package/module names\r\n\r\n> Note: Backwards-compatibility with positional arguments was intentionally removed. Use keyword-only parameters (`output_file_path=...`, `output_dir=...`).\r\n\r\n### [0.2.4] - 2025-06-30\r\n\r\n#### Changed\r\n- **Strict Python identifier enforcement**: Method names, class names, and parameter names extracted from SQL templates must now be valid Python identifiers. Invalid names will raise errors during code generation.\r\n- **Improved error messages**: Clearer error reporting when invalid names are detected in SQL templates.\r\n- **Documentation update**: The requirement for valid Python names is now explicitly documented in the README and enforced in the code generator.\r\n\r\n> **Note:** All method names, class names, and parameter names in your SQL templates must be valid Python identifiers (letters, numbers, and underscores, not starting with a number, and not a Python keyword). This ensures the generated code is always valid and importable.\r\n\r\n### [0.2.3] - 2025-06-29\r\n\r\n#### Changed\r\n- **Updated pyproject.toml**: Modernized build configuration with current best practices and comprehensive metadata\r\n- **Enhanced development setup**: Added optional dependency groups for dev, test, and docs tools\r\n- **Improved package metadata**: Added keywords, comprehensive classifiers, and better project description\r\n- **Type safety improvements**: Fixed all mypy type checking issues throughout the codebase\r\n- **Enhanced test coverage**: Added comprehensive test cases to achieve 81% overall coverage\r\n\r\n#### Technical Improvements\r\n- **Modern build system**: Upgraded to setuptools 68.0+ for better compatibility\r\n- **Development dependencies**: Added pytest, black, isort, flake8, mypy, and sphinx for development workflow\r\n- **Type annotations**: Added missing return type annotations and fixed type compatibility issues\r\n- **Code quality tools**: Integrated Black (formatter), isort (import sorter), flake8 (linter), and mypy (type checker)\r\n- **Comprehensive testing**: Added tests for CLI error handling, edge cases, and public API coverage\r\n- **Cross-platform compatibility**: Ensured all tests work reliably on Windows and Unix systems\r\n\r\n#### Development Experience\r\n- **One-command setup**: `pip install -e \".[dev]\"` installs all development tools\r\n- **Automated code formatting**: Black and isort ensure consistent code style\r\n- **Static analysis**: flake8 and mypy provide comprehensive code quality checks\r\n- **Test automation**: pytest with coverage reporting for quality assurance\r\n- **Documentation support**: Sphinx integration for generating project documentation\r\n\r\n### [0.2.2] - 2025-06-29\r\n\r\n#### Changed\r\n- **Simplified logger handling**: Removed optional `logger` parameter from all generated methods to always use class-level logger\r\n- **Cleaner API**: Reduced parameter clutter by eliminating the optional logger parameter\r\n- **Consistent logging**: All methods now use the same class-level logger for uniform logging behavior\r\n- **Updated test suite**: Modified tests to reflect the simplified logger approach\r\n\r\n#### Technical Improvements\r\n- **Simplified method signatures**: Generated methods now have fewer parameters and cleaner interfaces\r\n- **Consistent logging pattern**: Class-level logger approach follows common Python utility class patterns\r\n- **Reduced complexity**: Eliminated conditional logger assignment logic in generated code\r\n- **Better maintainability**: Generated code is simpler and easier to understand\r\n\r\n### [0.2.1] - 2025-06-29\r\n\r\n#### Changed\r\n- **Refactored `sql_helper.py`**: Improved error handling and input validation for file operations.\r\n- **Stricter type checks**: Functions now validate input types and raise clear exceptions for invalid arguments.\r\n- **Robust SQL parsing utilities**: Enhanced parsing and comment removal logic for more accurate statement detection and splitting.\r\n- **Improved documentation**: Expanded and clarified docstrings for all helper functions.\r\n\r\n### [0.2.0] - 2025-06-28\r\n\r\n#### Changed\r\n- **Switched to class-methods-only approach**: Removed instance methods and constructors for better transaction control\r\n- **Removed automatic commit/rollback**: Data modification operations no longer automatically commit or rollback, allowing explicit transaction management\r\n- **Added comprehensive logging**: All operations now include debug and error logging with customizable logger support\r\n- **Improved parameter formatting**: All method parameters are now on separate lines with proper PEP8 formatting\r\n- **Enhanced error handling**: Simplified exception handling without automatic rollback interference\r\n\r\n#### Technical Improvements\r\n- **Explicit transaction control**: Users must use `with connection.begin():` blocks for data modifications\r\n- **Better encapsulation**: No shared state between method calls, improving thread safety\r\n- **Named parameters required**: All methods use `*` to force named parameter usage for clarity\r\n- **Class-level logger**: Default logger with optional override per method call\r\n- **Production-ready**: Generated code is now suitable for production use with proper transaction management\r\n\r\n#### Generated Code Enhancements\r\n- **Transaction safety**: No automatic commits that could interfere with user-managed transactions\r\n- **Cleaner API**: Class methods only, no instance state to manage\r\n- **Better error propagation**: Exceptions are logged but not automatically rolled back\r\n- **Maintained API compatibility**: Public API remains consistent while improving safety\r\n\r\n### [0.1.1] - 2025-06-28\r\n\r\n#### Changed\r\n- **Refactored code generator to use Jinja2 templates**: Replaced string concatenation with template-based code generation for better maintainability and flexibility\r\n- **Added Jinja2 dependency**: Added `jinja2>=3.1.0` to requirements.txt\r\n- **Created templates directory**: Added `splurge_sql_generator/templates/` with `python_class.j2` template\r\n- **Simplified code generation logic**: Removed individual method generation functions in favor of template rendering\r\n- **Updated test suite**: Modified tests to work with new template-based approach while maintaining full functionality\r\n\r\n#### Technical Improvements\r\n- **Template-based generation**: All Python code is now generated using Jinja2 templates, making it easier to modify output format\r\n- **Better separation of concerns**: Template logic is separated from Python generation logic\r\n- **Maintained API compatibility**: Public API remains unchanged, ensuring backward compatibility\r\n- **Enhanced maintainability**: Code generation format can now be modified by editing templates without touching Python logic\r\n\r\n### [0.1.0] - 2025-06-28\r\n\r\n#### Added\r\n- Initial release of splurge-sql-generator\r\n- SQL template parsing with method name extraction\r\n- Sophisticated SQL statement type detection (fetch vs execute)\r\n- Support for Common Table Expressions (CTEs)\r\n- Python code generation with SQLAlchemy integration\r\n- Command-line interface for batch processing\r\n- Comprehensive parameter extraction and mapping\r\n- Support for complex SQL features (subqueries, JOINs, aggregations)\r\n- Auto-generated file headers with tool attribution\r\n- Robust error handling for file operations\r\n- Comprehensive test suite with edge case coverage\r\n\r\n#### Features\r\n- **SQL Helper Utilities**: `detect_statement_type()`, `remove_sql_comments()`, `parse_sql_statements()`\r\n- **Template Parser**: Extract method names and SQL queries from template files\r\n- **Code Generator**: Generate Python classes with proper type hints and docstrings\r\n- **CLI Tool**: Command-line interface with dry-run and batch processing options\r\n- **Statement Detection**: Automatic detection of fetch vs execute statements\r\n- **Parameter Handling**: Deduplication and proper mapping of SQL parameters\r\n\r\n#### Technical Details\r\n- Uses `sqlparse` for robust SQL parsing\r\n- Supports all major SQL statement types\r\n- Generates Python code with SQLAlchemy best practices\r\n- Comprehensive error handling and validation\r\n- MIT licensed with clear copyright attribution\r\n",
"bugtrack_url": null,
"license": null,
"summary": "A Python tool for generating Python classes from SQL files",
"version": "2025.3.0",
"project_urls": {
"Changelog": "https://github.com/jim-schilling/splurge-sql-generator/blob/main/CHANGELOG.md",
"Documentation": "https://github.com/jim-schilling/splurge-sql-generator#readme",
"Homepage": "https://github.com/jim-schilling/splurge-sql-generator",
"Issues": "https://github.com/jim-schilling/splurge-sql-generator/issues",
"Repository": "https://github.com/jim-schilling/splurge-sql-generator"
},
"split_keywords": [
"sql",
" code-generation",
" python",
" sqlalchemy",
" jinja2"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "7d665da3c5af20846e441056b813a5edfc62b810bdf0d5a55c574f7caf9ad3c0",
"md5": "b2b1f9480d33945c9d1cbfe0f3009b3f",
"sha256": "0e36bb0293c7d173f8d7a9ce85ddbeb6023b98a77db42f2fe28805bc09b0b56f"
},
"downloads": -1,
"filename": "splurge_sql_generator-2025.3.0.tar.gz",
"has_sig": false,
"md5_digest": "b2b1f9480d33945c9d1cbfe0f3009b3f",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 35017,
"upload_time": "2025-08-13T20:59:07",
"upload_time_iso_8601": "2025-08-13T20:59:07.476070Z",
"url": "https://files.pythonhosted.org/packages/7d/66/5da3c5af20846e441056b813a5edfc62b810bdf0d5a55c574f7caf9ad3c0/splurge_sql_generator-2025.3.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-13 20:59:07",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "jim-schilling",
"github_project": "splurge-sql-generator",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"requirements": [
{
"name": "sqlalchemy",
"specs": [
[
">=",
"2.0.39"
]
]
},
{
"name": "sqlparse",
"specs": [
[
">=",
"0.4.4"
]
]
},
{
"name": "jinja2",
"specs": [
[
">=",
"3.1.0"
]
]
}
],
"lcname": "splurge-sql-generator"
}