Change Log
All notable changes to this project will be documented in this file. This project adheres to Semantic Versioning.
Unreleased
v2.1.1
Fixed
FreeTDS 1.5.11 build failure on GCC 14+ due to -Wincompatible-pointer-types error in iconv.c.
Switched aarch64 wheel builds to native ARM runners, removing QEMU emulation.
v2.1.0
Added
Python 3.14 support.
__repr__forConnection,Cursor, andRowobjects for easier debugging. Examples:<k_ctds.Connection database='master' spid=54><k_ctds.Cursor (open, 3 columns)><k_ctds.Row(Col1=1, Col2='hello')>
Fixed
Memory leak in
Cursor.fetchall/fetchmany/fetchonewhen a SQL Server warning was promoted to a Python error viawarnings.filterwarnings('error'). Row buffers allocated duringdbnextrowwere not freed on the warning-as-error exit path inCursor_fetchrows. Detectable under Valgrind as definitely-lost bytes.
v2.0.0
Breaking Changes
Renamed import from
ctdstok_ctds. Users must now writeimport k_ctdsinstead ofimport ctdsto align with the PyPI package name (pip install k-ctds).Dropped FreeTDS 0.95 support. FreeTDS 1.0 or later is now required.
New Features
auto_encodeparameter forbulk_insert.bulk_insert(..., auto_encode=True)queriesINFORMATION_SCHEMA.COLUMNSto determine each column’s type and collation, then automatically encodes Pythonstrvalues: NVARCHAR/NCHAR/NTEXT columns are encoded to UTF-16LE, and VARCHAR/CHAR/TEXT columns are encoded to the column’s collation code page.SqlNVarCharnow produces correct output forbulk_insert. Previously,Parameter_bcp_bindsent UTF-8 bytes unchanged for NVARCHAR columns, silently corrupting data. It now re-encodes from UTF-8 to UTF-16LE when downgrading an explicitSqlNVarCharwrapper for FreeTDS BCP compatibility.
Build & Packaging
Migrated to
pyproject.tomlwith FreeTDS + OpenSSL bundled in wheels via cibuildwheelUpdated wheel builds to use OpenSSL 3.0 (built from source) across all platforms
Upgraded bundled FreeTDS to 1.5.11
Updated license files to reflect LGPL-2.0/Apache-2.0 compliance for bundled dependencies
Internal
Moved C extension from top-level
_tdstok_ctds._tdsUpdated all
tp_namestrings,DEFAULT_APPNAME, and C docstrings to usek_ctdsRenamed CI scripts and Docker container names (
ctds-→k-ctds-)Simplified test infrastructure by removing legacy FreeTDS 0.92/0.95 checks
Updated warning assertion tests to use
assertInfor substring matching
1.15.0 - 2026-02-11
Added
Support for SQL Server DATETIMEOFFSET data type (timezone-aware datetimes)
Support for Python 3.10, 3.11, 3.12, and 3.13
Comprehensive test suite for DATETIMEOFFSET operations (65 new tests)
Reading DATETIMEOFFSET values from SQL Server
Writing timezone-aware datetime values to SQL Server
Bulk insert operations with DATETIMEOFFSET
Backward compatibility tests for FreeTDS < 0.95
Changed
FreeTDS 0.95+ required for DATETIMEOFFSET (older versions still work but feature unavailable)
Compatibility
No breaking changes for existing code
[1.14.0] - 2021-03-25
Fixed
Replaced travis-ci with Github Actions.
Replaced custom Docker-based testing infrastructure with tox.
Fixed translation of SQL Server errors to Python exceptions for all errors with severity > 10. https://github.com/zillow/ctds/issues/84
[1.13.0] - 2020-11-12
Added
Offical support for Python 3.9.
Expose
ctds.Rowtype so that it can be used as a type annotation.Add
descriptionattribute to rowlists and rows.Add
ctds.Row.dict()method.
Fixed
Cache
cursor.descriptionrather than creating a new instance every time.
[1.12.0] - 2020-03-07
Fixed
Fixed Python -> SQL type conversion to consider client TDS version when choosing SQL type. https://github.com/zillow/ctds/issues/68.
Added Sphinx extension to auto-generate the
.nojekyllfile required by Github pages.Consolidate coverage output to a single directory.
[1.11.0] - 2019-11-14
Added
Official support for Python3.8.
Automate Python egg publishing to pypi.
Automate documentation publishing.
Fixed
Fix handling of
IDENTITYcolumns inctds.Connection.bulk_insert(). https://github.com/zillow/ctds/issues/59.
[1.10.1] - 2019-06-27
Fixed
Properly handle errors in the
ctds.pool.ConnectionPool.connectioncontext manager.
[1.10.0] - 2019-04-15
Added
Add FreeTDS 1.1 to test matrix.
Fixed
Preserve microsecond precision of TIME and DATETIME2 SQL types when converting to Python (and supported by FreeTDS).
Fix improper conversion of empty strings to
NULLinctds.Connection.bulk_insert(). https://github.com/zillow/ctds/issues/35.
[1.9.0] - 2018-11-05
Added
Add support for passing sequences of
dictvalues toctds.Connection.bulk_insert. The mapping key is used to determine the column order based on the column info available afterbcp_init. https://github.com/zillow/ctds/issues/38
Fixed
Fix truncation of strings containing multi-byte sequences when not using
sp_executesql.Fix
ctds.Cursor.executemany()truncating data for integer types. https://github.com/zillow/ctds/issues/43.
[1.8.0] - 2018-09-07
Added
Official support for Python 3.7.
Add optional
hostnameparameter toctds.connect(). https://github.com/zillow/ctds/issues/20.Add optional
ntlmv2parameter toctds.connect(). https://github.com/zillow/ctds/issues/27.
Fixed
Retry on SQL Server unittest database setup failures due to race conditions when starting SQL Server. This should make the unit tests much more reliable.
Add
python_requiresspecifier to setup.py.Properly handle decimal.Decimal values specified in scientific notation.
Properly set autocommit in
ctds.connect(), even whenansi_defaultsisFalse.Download FreeTDS packages from HTTP URL for compatibility with Travis CI builds (FTP no longer works due to firewall issues.)
Fix OS X Travis CI build.
Improve SQL Server -> DB API 2.0 error mappings. https://github.com/zillow/ctds/issues/12
Remove Python 2.6 from Appveyor CI due to lack of support.
Fix
ctds.Cursor.executemany()truncating data for variable width types. https://github.com/zillow/ctds/issues/25.
[1.7.0] - 2018-01-24
Added
Add rich comparison support and
reprtoctds.Parameter.
Fixed
Compiler warnings on older version of gcc.
Debug assert when passing invalid parameters to
ctds.Cursor.execute*().
[1.6.3] - 2017-12-05
Fixed
Raise proper warning from
ctds.Connection.messages.
[1.6.2] - 2017-11-27
Fixed
Support values longer than 8000 characters in
ctds.SqlVarChar.
[1.6.1] - 2017-11-20
Fixed
Revert passing BINARY 0x00 for (N)VARCHAR arguments.
[1.6.0] - 2017-11-17
Added
Documentation improvements.
Add an optional paramstyle argument to
ctds.connect, with support for thenamedparamstyle.Add valgrind support for memory leak detection and integrate it into the CI build process (Travis only).
Add optional
read_onlyargument toctds.connectfor indication of read-only intent. Note: Requires as yet unreleased FreeTDS support.
Fixed
Pass a BINARY 0x00 byte instead of an empty string for (N)VARCHAR arguments. This is to work around the inability of the db-lib API to pass empty string parameters via RPC.
[1.5.0] - 2017-10-16
Added
Windows support, with Appveyor continuous integration.
Python egg-related metadata checks.
Moved source code under ./src directory, per best practices.
[1.4.1] - 2017-09-29
Fixed
Only clear
Connection.messageson calls toexecute,executemanyorcallproc. Add support for raising multiple non-zero severity messages as warnings.
[1.4.0] - 2017-09-13
Fixed
Changed the implementation of
Cursor.executeto only perform parameter substitution if parameters are provided. When no parameters are passed, the SQL format string is treated as raw SQL.
Added
Connection.messagesread-only property.Improved code coverage.
[1.3.2] - 2017-07-25
Fixed
Register RowListType to support pickling/unpickling.
Added
Convert test framework to use Docker-based containers for SQL Server and for each supported combination of Python and FreeTDS.
Integrate codecov support for code coverage tracking.
Move documentation hosting to GitHub pages.
Include change log in generated documentation.
[1.3.1] - 2017-05-31
Fixed
Fix connection failures when connecting to high port numbers on OS X.
Fix unit test infrastructure to respect configured port number.
Work around inconsistencies between FreeTDS versions in the bcp_getl/ BCP_SETL interfaces.
[1.3.0] - 2017-03-15
Fixed
Replace usage of the deprecated
PyErr_WarnAPI withPyErr_WarnEx. This will allow clients to indicate that warnings should be raised as exceptions.
[1.2.3] - 2017-03-13
Fixed
Improve
reprimplementation for SQL type wrapper objects.Fixed informational (warning) message reporting where many SQL Server reported messages were not reported as warnings due if not returned to the client promptly enough.
[1.2.2] - 2017-01-10
Fixed
Fix multi-byte UTF-16 character conversion.
[1.2.1] - 2016-12-27
Fixed
Include
ctds.poolin egg package.
[1.2.0] - 2016-12-27
Fixed
Documentation improvements around (N)VARCHAR handling.
Added
ctds.pool.ConnectionPoolclass.Support the
inkeyword for resultset rows.Add code coverage support for Python code.
Improve code coverage support for c code.
[1.1.0] - 2016-11-14
Added
ctds.SqlNVarChartype.Ignore the replacement parameter markers inside of string literals in SQL statements passed to
ctds.Cursor.execute()andctds.Cursor.executemany().
Fixed
Work around a Memory leak in FreeTDS when specifying the database at connection time.
Fixed failure in
ctds.Cursor.execute()andctds.Cursor.executemany()when passing a SQL statement longer than 4000 characters.
[1.0.8] - 2016-08-17
Fixed
Configure connections to use UTF-16 when supported (i.e. FreeTDS 1.00+). Don’t replace codepoints outside of the UCS-2 range if the connection is using UTF-16 as it is no longer necessary and causes data loss.
[1.0.7] - 2016-08-15
Fixed
Only use strict compile options for debug/development builds. Allow the client (e.g. pip) to specify the desired options when installing as an egg.
[1.0.6] - 2016-08-15
Fixed
Compile under the c90 standard for better future portability.
Don’t overwrite more useful error messages with the useless “The statement has been terminated.” error.
Added
Minor documentation improvements.
[1.0.5] - 2016-05-23
Fixed
Fix the
ctds.Connection.timeoutproperty to raise an appropriate error when the option is supported, but the set fails.
[1.0.4] - 2016-05-19
Fixed
Fix the
ctds.Connection.timeoutproperty to work with the DBSETTIME option added in FreeTDS version 1.00.
Added
Support for TDS version 7.4, introduced with FreeTDS version 1.00.
[1.0.3] - 2016-03-31
Fixed
Fix execute() and executemany() to work with older versions of FreeTDS (prior to 0.92.405). Format the SQL command manually, instead of using sp_executesql, since older versions of FreeTDS don’t seem to support passing NVARCHAR arguments to remote procedure calls.
Added
Transaction documentation
Bulk insert documentation
[1.0.2] - 2016-03-15
Fixed
Documentation typos and improvements
Added
travis-ci integration
[1.0.1] - 2016-03-14
Fixed
Build on OS X
Added
Hypothetical integration with readthdocs.org
[1.0.0] - 2016-03-14
Initial Release