Repository navigation
chore: Release v1.0.0.dev2 - #1
Merged
Merged
Conversation
Implement comprehensive SQL Server backend for rhosocial-activerecord: Core Components: - config.py: Connection configuration with Windows/SQL authentication - dialect.py: SQL Server dialect with T-SQL specific syntax - backend.py: Synchronous backend using pyodbc - async_backend.py: Asynchronous backend using aioodbc - transaction.py: Transaction management with savepoint support - async_transaction.py: Async transaction manager Type System: - adapters.py: Type adapters for UUID, DateTime, JSON, XML, Spatial types SQL Server Features: - OUTPUT clause (similar to RETURNING) - OFFSET FETCH pagination (SQL Server 2012+) - MERGE statement for upsert - CROSS APPLY/OUTER APPLY instead of LATERAL - SNAPSHOT isolation level - IDENTITY columns Additional: - explain/: EXPLAIN result types - introspection/: Schema introspector - examples/: Usage examples (connection, query, transaction, DDL) - protocols.py: SQL Server specific protocols - mixins.py: SQL Server backend mixins
Update all example files to: - Load connection configuration from environment variables - Provide sensible default values for all settings - Be self-contained without external config file dependencies - Follow the style of sqlite examples Environment variables (with defaults): - SQLSERVER_HOST (localhost) - SQLSERVER_PORT (1433) - SQLSERVER_DATABASE (test_db) - SQLSERVER_USERNAME (sa) - SQLSERVER_PASSWORD (Password123!) - SQLSERVER_DRIVER (ODBC Driver 17 for SQL Server) - SQLSERVER_ENCRYPT (false) - SQLSERVER_TRUST_SERVER_CERTIFICATE (true)
Update all example files to: - Add clear SECTION comments (Setup, Business Logic, Execution, Teardown) - Use expression-based SQL instead of raw SQL strings - Follow the SQLite examples structure and style - All SQL is generated via expressions (CreateTableExpression, QueryExpression, etc.) New files added: - examples/README.md: Directory structure and usage guide - examples/ddl/create_index.py: Index creation example - examples/insert/batch.py: Batch insert example - examples/insert/with_output.py: OUTPUT clause example (SQL Server's RETURNING) - examples/query/join.py: JOIN examples - examples/types/json_basic.py: JSON operations Key principles: - Self-contained: Each file runs independently - Clear sections: Setup/Teardown marked as reference only - Pure business logic: Core expression usage is copyable - Expression-based: All SQL via Expression-Dialect architecture
…lect methods - Add get_default_adapter_suggestions() to backend for type adapter support - Add format_limit_offset_clause() for OFFSET FETCH syntax (SQL Server 2012+) - Fix OUTPUT clause position in INSERT statements (before VALUES) - Add format_create_index_statement() for SQL Server CREATE INDEX syntax - Update config.py to support legacy 'SQL Server' ODBC driver - Fix all example files to use correct driver and port defaults - Fix join.py example to use JoinExpression correctly
- Add Python 3.8, 3.9, 3.13, 3.14 and free-threaded versions (3.13t, 3.14t) - Distribute Python versions across SQL Server 2019, 2022, 2025 - Fix healthcheck command path: /opt/mssql-tools18/bin/sqlcmd - Add explicit ODBC Driver 17 installation step - Use autocommit=True for database creation - Update pyodbc dependency to >=5.3.0
- Add test suite structure following MySQL/SQLite patterns - test_dialect.py: Test dialect formatting methods (OFFSET FETCH, identifiers) - test_config.py: Test connection configuration and validation - test_backend.py: Test backend functionality with real database (sync/async) - test_expressions.py: Test SQL Server-specific expression formatting - Add conftest.py with fixtures for backend setup and scenario loading - Update pytest.ini with test configuration and markers
- Add aioodbc>=0.5.0 to requirements.txt for async support - Fix dialect tests to use correct method names (supports_returning_clause, etc.) - Fix OFFSET FETCH tests - SQL Server requires LIMIT with OFFSET - Fix async backend tests to use transaction_manager.begin()/commit() - Remove is_connected() assertion (method not available in backend) - All 45 tests now passing
…d-query/procedure/connection subcommands Refactor SQL Server backend CLI to match the modular subcommand architecture used by postgres/sqlite backends. Add ODBC driver compatibility fixes for nvarchar(max) columns and SERVERPROPERTY() with legacy drivers.
- Add execute_many tests for batch operations - Add transaction savepoint tests - Add transaction isolation level tests - Add async CRUD tests - Add JSON expression tests (SQL Server 2016+) - Add DDL features tests (SELECT INTO) These tests close the feature gap with MySQL and PostgreSQL backends.
- Fix execute_many empty param list handling (return 0 affected rows) - Fix async execute_many empty param list handling - Fix JSON adapter method names (to_database/from_database) - Update test assertions to not rely on affected_rows
- Add JSON functions (json_value, json_query, is_json, json_object, json_array) - Add string functions (string_agg, concat_ws, trim, format, string_split) - Add datetime functions (eomonth, datefromparts, datetime2fromparts, timefromparts) - Add utility functions (iif, choose, try_cast, try_convert, try_parse, coalesce, nullif) - Add tests and examples
…omprehensive tests - Add 10+ SQL Server-specific protocol extensions (TableSupport, LockingSupport, JSONSupport, TemporalTable, Sequence, FullTextSearch, Pagination, Merge, etc.) - Add 6 expression modules: output (INSERTED/DELETED), locking (table hints), openjson (OPENJSON with schema), temporal (SYSTEM_VERSIONING), functions (TRY_CAST, TRY_CONVERT, CONTAINS, FREETEXT) - Add 16 format_* method overrides to SQLServerDialect for SQL Server-specific syntax (SEQUENCE, SCHEMA, TRUNCATE, MERGE, LATERAL→CROSS/OUTER APPLY, FOR UPDATE→table hints, set operations, ALTER TABLE, full-text, TOP n) - Add 78 comprehensive dialect unit tests - Fix format_update_statement (assignments→values) and format_delete_statement (table→tables) API compatibility
…dencies - Change dialect __init__ default version from (16,0,0) to None, call super().__init__() first to enforce version adaptation via introspect_and_adapt() - Replace supports_returning_clause() with DML-specific supports_returning_insert/update/delete() (all True, OUTPUT clause) - Fix DEFAULT value escaping: use _escape_sql_string() instead of manual inline replace - Add constraint capability overrides: supports_constraint_enforced() (False), supports_fk_match() (False), supports_deferrable_constraint() (False) - Bump CI: activerecord to release/v1.0.0.dev27, testsuite to release/v1.0.0.dev14 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Fix savepoint() to return name (str) instead of None, matching base class TransactionManager signature - Change savepoints from property to method, matching test expectations - Fix isolation level handling: separate SQLServerIsolationLevel from base IsolationLevel, resolve from base class property in begin() - Fix test_supports_isolation_level to use supports_isolation_level_in_begin() (correct method name) - Fix all SQLServerDialect() instantiations in tests to pass version=(16,0,0) to avoid DialectNotAdaptedException Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…nager - Add AsyncSQLOperationsMixin to async backend class hierarchy so fetch_one/fetch_all are async and properly await execute() - Add AsyncTransactionManagementMixin for async transaction context manager support - Fix AsyncSQLServerTransactionManager.savepoint() to return name (str) instead of None, matching base class signature - Change savepoints from property to method for API consistency - Add isolation_level property to async transaction manager with proper SQLServerIsolationLevel resolution - Add @asynccontextmanager decorator to transaction() method - Separate _sqlserver_isolation_level from base IsolationLevel to prevent enum value being used as SQL string Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…efaults - Remove db-dev-1-n.rho.im and hardcoded passwords from test_connection.py - Fix all 10 examples to use empty default password instead of Password123! - Fix examples/README.md documented default password - Remove hardcoded --password secret from CLI docstrings - Add test_connection.py to .gitignore to prevent future leakage
- Replace Password123! default with empty string in all 10 examples - Fix examples/README.md documented default password - Remove --password secret from CLI docstrings (use env vars instead)
…lect compat - Add bridge test files for basic/connection/worker, events, mixins, query - Add native backend tests: dialect_function_support, cli, explain, async_error_handling, transaction_backend, connection_resilience - Add SQL Server test providers with FK-safe DROP TABLE and DropTableExpression - Add pytest.ini with markers and SQLAlchemy-style scenario markers - Convert SQLServerConnectionConfig to @DataClass inheriting ConnectionConfig - Add encrypt_connection ↔ encrypt bridge via __post_init__ - Override _build_query_result to handle cursor.rowcount = -1 with OUTPUT INSERTED - Override format_update_statement/format_delete_statement (remove double WHERE) - Override format_returning_clause with default_table param (INSERTED/DELETED) - Override format_query_statement to append ORDER BY (SELECT NULL) for OFFSET - Add version-gated supports_* methods for sequences, IF EXISTS (2012/2016+) - Fix all SQLServer*Adapter.to_database/from_database to accept target_type/options - Fix SQLServerDateTimeAdapter.from_database string path to add UTC tzinfo - Register Python-type-to-Python-type mappings in _register_sqlserver_adapters - Add (dict,str)/(list,str) to get_default_adapter_suggestions for JSON support
…nc execute pipeline - Move get_default_adapter_suggestions to SQLServerBackendMixin so both sync and async backends share the implementation - Rewrite AsyncSQLServerBackend.execute to use parameter preparation (to_database via adapter suggestions) and result processing (_adapt_row_types via column_adapters/column_mapping) - Use _build_query_result from mixin to handle cursor.rowcount = -1 with OUTPUT clause by computing len(data) instead - Fix test_dialect_comprehensive.py: assert DELETED instead of INSERTED for DELETE OUTPUT clause
- Create bridge files for all 26 query test files (sync + async) - Create bridge files for connection/ subpackage (3 test files) - Create bridge files for worker/ subpackage (2 test files) - Add conftest.py bridge files for query/, connection/, worker/ - Register requires_protocol, requires_functions, requires_inner_join markers in root conftest (testsuite markers not auto-loaded from pkg) - Fix query provider FK drop issue: add _drop_table_safely with _FK_DEPENDENCY_MAP to safely drop FK-referenced tables before target table (prevents SQL Server error 3726) - Fix comments.sql FK cascade: change ON DELETE CASCADE to ON DELETE NO ACTION on both FKs (prevents error 1785)
…ting SQL Server uses bracket quoting []. Tests verify: - Normal, embedded-bracket, and injection payload cases - Naive vs proper bracket escaping for safe and malicious input - Bracket counts are balanced and breakout is prevented
…nd feature tests - dialect: map LENGTH/CHAR_LENGTH to LEN, JSON_EXTRACT/JSON_UNQUOTE to JSON_VALUE via _clone_with_func_name and format_json_function_expression - backend_mixin: SQL Server version string parsing and connection logging - backend/async_backend: MERGE trailing semicolon, connection stability and async pool initialization fixes - functions: add aggregate/bitwise/math/spatial factories, SHOW functionality module, JSON/string function adaptations - tests: replace testsuite bridge skip-helper with proper SQL Server expectations (trailing-space trim, READ_COMMITTED_SNAPSHOT pool behavior, OBJECT_ID existence checks, table-like DDL) - relation derived/integration bridges no longer skip testsuite coverage - add pytest-benchmark to dev requirements for benchmark test infra
…event CI hang The previous per-module autouse fixture ran ALTER DATABASE ... SET READ_COMMITTED_SNAPSHOT when the connection tests began, by which point earlier worker/concurrency tests had opened connections against the database. Because this ALTER requires an exclusive database lock, the fixture blocked forever (CI observed >50 minutes with no progress) and the missing MVCC semantics also caused parallel-CRUD worker tests to fail. Move the enabling logic to a session-level autouse fixture in the root tests conftest, which runs before any test opens a connection, uses a LOCK_TIMEOUT and retries, and skips databases already configured.
ODBC and older Python runtimes deliver datetime2 values as strings with seven fractional digits (100ns precision). datetime.fromisoformat capped at 6 digits on Python < 3.13, raising ValueError during row adaption. Normalize the string before parsing: map 'Z' to +00:00, restore the T separator, and drop fractional digits beyond 6.
…ct server version on connect
…ise core dependency - Scenario filtering reads generic TESTSUITE_ACTIVE_SCENARIOS env var (fallback from backend-local SQLSERVER_ACTIVE_SCENARIOS) so --scenarios works when running tests from either the testsuite dir or this repo - Raise rhosocial-activerecord dependency floor to >=1.0.0.dev0 - Fix relation/derived bridge imports to correctly named testsuite modules - Add changelog fragment
…emaDiffer The core migrated schema-diff resolution to the dependency-inversion hook SQLDialectBase.create_schema_differ() and no longer imports concrete backend differs. Override the hook so SQL Server keeps its ordinal-position-aware column comparison in migration snapshot diffs. - Implement SQLServerDialect.create_schema_differ() returning SQLServerSchemaDiffer - Add changelog fragment
Welcome to Codecov 🎉Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests. Thanks for integrating Codecov - We've got you covered ☂️ |
vistart
marked this pull request as ready for review
August 15, 2026 10:28
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.




Description
This is the first development release (
v1.0.0.dev2) of the SQL Server backend implementation for rhosocial-activerecord. It provides a complete SQL Server backend, including dialect mappings, T-SQL-specific DDL support, expression-level COLLATE, datetime2 handling, and comprehensive test infrastructure bridges.Release/Hotfix Details
v1.0.0.dev2Development ReleaseNew Features
SQLServerPartitionMixin), in-memory OLTP options, indexed views, full-text catalog, columnstore, SELECT INTO, PIVOT/UNPIVOT, TABLESAMPLE, OPTION hints, NEXT VALUE FOR, MERGE OUTPUT/HOLDLOCK, IF EXISTS for DROP COLUMN/CONSTRAINTSQLServerSchemaDifferfor schema snapshot diff/comparisonnamed-migrationCLI subcommand with sync and--asyncsupportBug Fixes
READ_COMMITTED_SNAPSHOTat session start to prevent CI hang__repr__for coreConnectionConfigprotocol compatibilityparse_typeVARCHAR/NCHAR detectionTest Infrastructure
TESTSUITE_PROVIDER_REGISTRY) andTESTSUITE_ACTIVE_SCENARIOSfiltering supportRelated Issues/PRs
Initial development release for the SQL Server backend; no prior release exists.
Breaking Change
Applicable
rhosocial-activerecordVersion Range:>=1.0.0,<2.0.0Testing
Test Plan: Full test suite execution (covered by CI on the release branch)
Checklist
CHANGELOG.mdusingtowncrier build(will be done after PR approval)Additional Notes
This is the first development release (dev2) of the SQL Server backend. The changelog will be built using towncrier after this PR is approved and CI checks pass.