Skip to main content

ArpeMSSQL — Connection guide

Everything you can put in front of ArpeMSSQL to point it at a SQL Server, in one place: the three ways to supply connection details, every option the driver accepts, and the SQL Server-specific rules (named instances, Azure SQL / Fabric, Entra ID).

For integrated (Windows) authentication, see Authentication. For the licence, see Licensing.


Three ways to connect​

Every driver in the Arpeio family accepts the same three connection forms. They can be mixed; a discrete option always wins over the same field taken from a connection_string or a uri, regardless of the order they are set.

FormOption keyGrammarBest for
Discrete optionsadbc.arpemssql.<field>one option per fieldprogrammatic clients, secrets kept out of a single string
Connection stringadbc.arpemssql.connection_string (alias connection_string)ADO.NET Key=Value;…pasting an existing SQL Server / SqlClient string
Connection URIurisqlserver://… URLportable tooling, copy-paste from go-mssqldb/ADBC tools
Python
import adbc_driver_manager.dbapi as dbapi

# Discrete options
conn = dbapi.connect(driver="arpemssql", db_kwargs={
"adbc.arpemssql.server": "localhost",
"adbc.arpemssql.database": "tpch",
"adbc.arpemssql.username": "sa",
"adbc.arpemssql.password": "<password>",
"adbc.arpemssql.encrypt": "true",
"adbc.arpemssql.trust_server_cert": "true",
})

# Connection string
conn = dbapi.connect(driver="arpemssql", db_kwargs={
"adbc.arpemssql.connection_string":
"Server=localhost;Database=tpch;User ID=sa;Password=<password>;"
"Encrypt=true;TrustServerCertificate=true",
})

# Connection URI
conn = dbapi.connect(driver="arpemssql", db_kwargs={
"uri": "sqlserver://sa:<password>@localhost:1433/"
"?database=tpch&encrypt=true&TrustServerCertificate=true",
})

Precedence: a field parsed from connection_string/uri is applied only if no discrete adbc.arpemssql.* option already set it.


Option reference​

All options are string-typed and live under the adbc.arpemssql.* namespace (a few also accept a short bare alias, noted below). Set them as ADBC database options before the connection is opened. Statement/ingest options are set on the statement — see Statement & ingest options.

Boolean options take true / false. Keywords in a connection_string are parsed case-insensitively (see Connection string).

Target — where to connect​

OptionAliasDefaultMeaning
adbc.arpemssql.serverhostname—Host, host,port / host:port / [::1]:port, ./(local) (→ localhost), or a named instance host\INSTANCE. See Named instances.
adbc.arpemssql.portport1433TCP port, 1..65535. Ignored for a named instance unless given explicitly.
adbc.arpemssql.databasedatabaseserver defaultInitial database.
adbc.arpemssql.app_nameapp_namedriver defaultProgram name reported to the server (sys.dm_exec_sessions.program_name).
adbc.arpemssql.application_intent—ReadWriteReadOnly / ReadWrite (any case; anything else → INVALID_ARGUMENT). Since v0.6.7. ReadOnly declares a read-only workload at login, so an Availability Group listener with read-only routing sends the connection to a readable secondary. See Read-only routing.

Authentication​

Full method-by-method detail is in Authentication; the cloud/Entra options are described under Azure SQL, Microsoft Fabric & Entra ID.

OptionValuesMeaning
adbc.arpemssql.username / .passwordstringSQL-authentication credentials (aliases username / password).
adbc.arpemssql.trustedtrue/1/yes/sspi/SSPI, false/0/noIntegrated auth via Windows SSPI (Kerberos), no username/password. Windows only — not available on Linux. Alias trusted.
adbc.arpemssql.auth_typesql/SqlPassword, integrated/sspi/trusted, ActiveDirectoryDefault/defaultSelects the auth mode explicitly. Any other value, including the other ActiveDirectory* modes, is rejected with NOT_IMPLEMENTED and a pointer to the supported options.
adbc.arpemssql.krb5.spnSPNIntegrated auth (Windows): override the derived service principal name (MSSQLSvc/host:port). See SPN.

Encryption / TLS​

OptionDefaultMeaning
adbc.arpemssql.encryptlogin-onlytrue/false (also 1/0, yes/no). true encrypts the whole session (TLS 1.2+, SNI, cert + hostname verification). Azure SQL requires true.
adbc.arpemssql.trust_server_certfalsetrue skips server-certificate/hostname verification (self-signed dev servers). Leave false in production.
adbc.arpemssql.allow_cleartext_loginfalsePermit the credentials-in-cleartext login exchange when encryption is off.

With encrypt=true and trust_server_cert=false the server certificate and hostname are verified by default; an IP-literal host is checked against the certificate's iPAddress SAN. There is no CA-file option: the certificate is checked against OpenSSL's default locations, which hold no CAs on RHEL and Windows. See Authentication → TLS for what is encrypted in each mode, the TLS version floor and where trusted certificates come from on each OS.

Cloud / Entra ID (Azure SQL & Microsoft Fabric)​

OptionMeaning
adbc.arpemssql.access_tokenCaller-supplied Entra ID bearer token (passthrough).
adbc.arpemssql.tenant_id / .client_id / .client_secretService principal; the driver acquires a token via OAuth2 client credentials at connect.
adbc.arpemssql.managed_identitytrue/system (system-assigned) or a user-assigned identity's client id; the driver acquires the token from the Azure host, no secret.

See Azure SQL, Microsoft Fabric & Entra ID.

Timeouts & performance​

OptionDefaultMeaning
adbc.arpemssql.login_timeout30TCP connect budget in seconds (0 = the default, 30). When a host resolves to several addresses they share this budget, so one dead address cannot stall the connect.
adbc.arpemssql.query_timeout0Per-query timeout in seconds (0 = no limit).
adbc.arpemssql.buffer_size32000Rows per streamed Arrow batch (per connection); also the default statement batch_size. Capped at 10,000,000 (larger values are clamped with a warning). The driver auto-flushes early if a wide utf8/binary column would cross Arrow's 2 GiB offset limit, so large values are safe.
adbc.arpemssql.packet_size8192TDS network packet size requested at login (the server may answer with its own). 0 = the driver default (8192); otherwise 512..32767 (MS-TDS spec maximum).

Type rendering (read path)​

OptionValuesMeaning
adbc.arpemssql.uuid_casinglower (default) / upper (also lowercase / uppercase)Hex case of uniqueidentifier/GUID values rendered to Arrow utf8. lower matches RFC 4122 and the mssql connection type.
adbc.arpemssql.geospatialgeoarrow (default) / wkb / varbinaryHow geometry/geography (CLR UDT) columns are read. See Geospatial types.
adbc.arpemssql.timestamp_precisionmicrosecond (default, also micro / us) / nanosecond (also nano / ns)Since v0.6.2. Max Arrow precision for scale-7 DATETIME2/DATETIMEOFFSET/TIME. microsecond caps at µs (Parquet TIMESTAMP_MICROS, Spark-friendly); nanosecond keeps full 100 ns resolution. Scales 0–6 unaffected. See Temporal types.

Ingest SRID (write path)​

Version

Since ArpeMSSQL v0.5.25.

OptionDefaultMeaning
adbc.arpemssql.ingest.sridunset (-1)SRID stamped into geometry/geography values written on the Arrow WKB → UDT ingest path, for columns whose GeoArrow crs metadata does not give one (a crs on the column takes precedence). Must be an integer >= -1. When unset, such columns get the kind default (geometry 0, geography 4326). See Write path.

Licence​

OptionMeaning
arpeio.adbc.licenseLicence blob, inline.
arpeio.adbc.license_filePath to a .lic file.
arpeio.adbc.license.statusRead-only (GetOption); reports <state>;code=<ARROW_LIC_*>;tier=<tier>;expires=<epoch>.

The driver also reads the shared ARPEIO_ADBC_LICENCE[_FILE] environment variables and an arpeio_adbc.lic file next to the library. Full resolution order in Licensing.

Standard ADBC connection options​

These use the ADBC-standard keys (no arpemssql namespace):

OptionValuesMeaning
adbc.connection.autocommittrue (default) / falseAutocommit mode. Accepted as a database option or on an open connection. With false, a bulk ingest runs inside your open transaction and is kept or undone by commit / rollback; with true, each ingest is its own transaction (see arpemssql.bulk_atomic).
adbc.connection.catalogdatabase nameSwitches the current database (USE [db] on the open session; with no session yet, validated by a test login). Empty is rejected.
adbc.connection.db_schemaschema nameChecked with SCHEMA_ID(...) (missing schema → NOT_FOUND) and stored client-side: SQL Server has no per-session default schema. Empty is rejected.
adbc.connection.transaction.isolation_levelread_uncommitted / read_committed / repeatable_read / snapshot / serializable / defaultValues take the adbc.connection.transaction.isolation. prefix. Maps to SET TRANSACTION ISOLATION LEVEL; survives an internal reconnect. .linearizable → NOT_IMPLEMENTED (no SQL Server equivalent); any other value → INVALID_ARGUMENT.
adbc.connection.readonlyfalse / 0Accepted as a no-op; true/1 → NOT_IMPLEMENTED (SQL Server has no session read-only mode).

catalog, db_schema, isolation_level and readonly are connection options (set on the open connection), not database options.

Statement & ingest options​

Set on the statement handle, not the database:

OptionDefaultMeaning
adbc.arpemssql.batch_sizebuffer_size (32000)Rows per Arrow batch for this statement, 1..max_batch_size. Defaults to the database's adbc.arpemssql.buffer_size.
adbc.arpemssql.max_batch_size1000000Upper bound for batch_size; must be >= the current batch_size.
adbc.arpemssql.memory_budget_mb256Decode memory budget, 16..8192 MB.
adbc.ingest.target_table—Target table for adbc_ingest (bulk load via INSERT BULK).
adbc.ingest.modecreateadbc.ingest.mode.create / .append / .replace / .create_append (the short forms create, append, … also match).
adbc.ingest.target_catalog—Target database for ingest.
adbc.ingest.target_db_schema—Target schema for ingest.
adbc.ingest.temporaryfalsetrue/1 ingests into a session temp table (#name).

Bulk-insert options​

Set on the statement before adbc_ingest. Each option except bulk_atomic and bulk_order also accepts the older bcp_ spelling (e.g. arpemssql.bulk_tablock == arpemssql.bcp_tablock). Booleans take true / false. The defaults favour load speed, matching SQL Server's BULK INSERT fast-load behaviour.

OptionAliasDefaultMeaning
arpemssql.bulk_tablockarpemssql.bcp_tablocktrueTake a bulk-update table lock — required for minimal logging.
arpemssql.bulk_batch_sizearpemssql.bcp_batch_size10000000Rows per sub-batch sent to the server, 1..100000000.
arpemssql.bulk_atomic—trueWith autocommit=true, run the whole ingest (DDL for create / replace included) as one transaction, so a failure leaves the table as it was. false commits each sub-batch on its own: a failure then leaves the earlier sub-batches committed, but the transaction log only has to hold one sub-batch at a time. Ignored with autocommit=false, where the ingest is part of the caller's transaction. Accepts only true/false/1/0.
arpemssql.bulk_keep_identityarpemssql.bcp_keep_identityfalsetrue loads the source's values into the target's IDENTITY column. false leaves the column out of the load, so the server numbers the rows and any source values for it are ignored. Not for temporary (#) tables: there an IDENTITY column must be left out of the source.
arpemssql.bulk_check_constraintsarpemssql.bcp_check_constraintsfalseEnforce CHECK/FK constraints during load (off = faster).
arpemssql.bulk_fire_triggersarpemssql.bcp_fire_triggersfalseFire INSERT triggers during load (off = faster).
arpemssql.bulk_keep_nullsarpemssql.bcp_keep_nullstrueKeep source NULLs instead of applying column DEFAULTs.
arpemssql.bulk_order——ORDER hint: the order the data is already sorted in, as col [ASC|DESC], ... (columns of the load; [bracket] names with spaces or commas; an IDENTITY column only with bulk_keep_identity=true). When it matches the clustered index the server can skip its sort; data not in that order is then rejected (error 4819). Empty clears it.
Version

arpemssql.bulk_atomic since ArpeMSSQL v0.6.5; arpemssql.bulk_order since ArpeMSSQL v0.6.6.

Coming from SqlBulkCopy:

SqlBulkCopyOptions / propertyArpeMSSQL statement option
TableLockarpemssql.bulk_tablock — on by default here
KeepNullsarpemssql.bulk_keep_nulls — on by default here
CheckConstraintsarpemssql.bulk_check_constraints
FireTriggersarpemssql.bulk_fire_triggers
KeepIdentityarpemssql.bulk_keep_identity
UseInternalTransactionarpemssql.bulk_atomic=false (with autocommit=true)
BatchSizearpemssql.bulk_batch_size
ColumnOrderHintsarpemssql.bulk_order
AllowEncryptedValueModifications— (Always Encrypted is not supported)

SqlBulkCopyOptions.Default corresponds to bulk_tablock=false and bulk_keep_nulls=false. With every hint off the INSERT BULK carries no WITH clause and takes row locks rather than the bulk-update table lock.

Accepted no-ops (back-compat)​

Recognised and ignored so strings copied from ODBC-era tooling still load:

  • Database options: adbc.arpemssql.mars, adbc.arpemssql.compression.
  • Connection options (set on an open connection): adbc.arpemssql.mars, adbc.arpemssql.enable_compression, and the bare mars / compression.
  • Statement options: adbc.arpemssql.prefetch.

adbc.arpemssql.application_intent is no longer a no-op since v0.6.7 (see Read-only routing).

The removed BCP knobs arpemssql.use_bcp, arpemssql.bcp_order_hint and arpemssql.bcp_auto_order are still accepted on the statement but have no effect and log a deprecation warning. The other arpemssql.bcp_* keys are live aliases of the bulk-insert options.


Connection string (ADO.NET form)​

adbc.arpemssql.connection_string (alias connection_string) accepts the ADO.NET Key=Value;… grammar: case-insensitive keywords, quoted values, doubled-quote escapes. Keywords map onto the options above; an unknown keyword is rejected. Boolean values (yes/no/true/false/1/0) are case-insensitive here.

Keyword(s)Option
Server, Data Source, Address, Addr, Network Addressserver (host, host,port, optional tcp: prefix; other protocol prefixes are rejected)
Database, Initial Catalogdatabase
User ID, UID, Userusername
Password, PWDpassword
Application Name, Appapp_name
Encryptencrypt
TrustServerCertificatetrust_server_cert
AllowCleartextLoginallow_cleartext_login
Connection Timeout, Connect Timeout, Timeoutlogin_timeout
Packet Size, PacketSizepacket_size (0 or 512..32767)
ApplicationIntent, Application Intent (ReadOnly / ReadWrite)application_intent (since v0.6.7)
Integrated Security, Trusted_Connection, Trusted Connection (SSPI/yes/true/1, no/false/0)trusted (integrated auth is Windows only)
Authenticator (sspi/winsspi/krb5 → integrated, sql → SQL login)trusted
Authenticationauth mode: only SqlPassword (or Sql Password) is accepted; any ActiveDirectory* value → NOT_IMPLEMENTED, anything else → INVALID_ARGUMENT
Service Principal Name, ServicePrincipalName, service_principal_namekrb5.spn

Integrated Security, Trusted_Connection, Authenticator and Authentication all set the same auth-mode field, so giving two of them is a duplicate-key error. For Entra ID use the discrete options (access_token, client_secret, managed_identity, auth_type); they have no connection-string keyword.

Server=localhost\SQL2022;Database=tpch;User ID=sa;Password=secret;Encrypt=true;Packet Size=8192

Connection URI​

Version

Since ArpeMSSQL v0.5.19.

The standard ADBC uri option takes the portable SQL Server URL used by the official drivers (Microsoft go-mssqldb, the ADBC Foundry driver), so a string copied from other SQL Server ADBC tooling works unchanged.

<scheme>://[user[:password]]@host[:port][/INSTANCE][?key=value&…]
  • Schemes (case-insensitive, equivalent): sqlserver://, mssql://, and the branded arpemssql://. The scheme only selects the URL grammar — it never picks the driver, so sqlserver:///mssql:// never collide with another SQL Server ADBC driver installed alongside this one.
  • The path segment is the SQL Server instance name (folded into host\INSTANCE), not the database — the database is the database query parameter. This matches go-mssqldb; it is the one surprising part of the grammar.
  • userinfo and query values are percent-decoded; query values treat + as a space (connection+timeout ≡ connection timeout). IPv6 hosts use the bracketed form: sqlserver://[::1]:1433/?database=d.

Query parameters (matched case-insensitively; unknown or repeated parameters are rejected):

Parameter(s)Option
database, initial catalogdatabase
user id, user, uidusername
password, pwdpassword
encryptencrypt
TrustServerCertificatetrust_server_cert
connection timeout, connect timeout, dial timeoutlogin_timeout
packet sizepacket_size
app name, application nameapp_name
ApplicationIntentapplication_intent (since v0.6.7; accepted and ignored before)
fedauth, hostNameInCertificaterecognised, not yet implemented: any value → NOT_IMPLEMENTED

For Entra ID today, pass a bearer token via the adbc.arpemssql.access_token option rather than a fedauth URL parameter — see Azure SQL, Microsoft Fabric & Entra ID.


Read-only routing (ApplicationIntent)​

Version

Since ArpeMSSQL v0.6.7. Earlier versions accepted ApplicationIntent and ignored it.

ApplicationIntent=ReadOnly (or adbc.arpemssql.application_intent=ReadOnly) sets the read-only-intent flag in the login. When the connection goes to an Availability Group listener with read-only routing configured, SQL Server answers with a redirect to a readable secondary and the driver reconnects there, with the same intent. As with SqlClient:

  • Name the database (Database / Initial Catalog): routing applies to a database in the Availability Group.
  • Connecting to a replica instance directly, not through the listener, is not routed.
  • A secondary configured with ALLOW_CONNECTIONS = READ_ONLY refuses connections without the read-only intent.
  • On a server outside an Availability Group the flag is ignored.
Server=ag-listener;Database=sales;ApplicationIntent=ReadOnly;User ID=reporter;Password=<password>;Encrypt=true

ReadWrite, the default, sends no intent. MultiSubnetFailover (trying every IP of a multi-subnet listener in parallel) is not supported.


Named instances​

Version

Since ArpeMSSQL v0.5.14.

A SQL Server named instance normally listens on a dynamic TCP port, not 1433. Given Server=host\INSTANCE, the driver asks the SQL Server Browser on UDP port 1434 which port the instance uses, then connects there — the same handshake SqlClient performs. Both the query path and the INSERT BULK path use it.

Server=localhost\DATAQ1          # port discovered via the Browser
Server=.\SQLEXPRESS # "." and "(local)" mean this machine
Server=localhost\DATAQ1,54312 # explicit port: no Browser lookup at all
  • UDP 1434 must be reachable and the Browser service must be running. If it does not answer, the connection fails after ~3 s with a message naming the instance and the workaround. The driver never falls back to 1433 on its own.
  • An explicit port bypasses the lookup (including an explicit ,1433) — the escape hatch when the Browser is firewalled off.
  • (localdb)\... is rejected: LocalDB is reached over a named pipe, not TCP.

For integrated auth (Windows) the Kerberos SPN is derived after resolution, as MSSQLSvc/host:<resolved-port>. See Authentication.


Azure SQL, Microsoft Fabric & Entra ID​

Version

Entra ID authentication since ArpeMSSQL v0.5.20.

SQL-authentication connections to *.database.windows.net work out of the box — TLS 1.2+, SNI, and hostname verification are on the default path (use encrypt=true). Both the Proxy and Redirect gateway policies are supported: on Redirect the driver follows the gateway's ENVCHANGE ROUTING token and reconnects to the database node transparently (needs outbound TCP to ports 11000–11999).

Entra ID (Azure AD) authentication has four modes, all over verified TLS. Federated auth always uses full TLS and cannot be combined with a username/password.

1. Access-token passthrough​

Supply a bearer token you acquired out-of-band:

Python
import subprocess, adbc_driver_manager.dbapi as dbapi

token = subprocess.check_output(
["az", "account", "get-access-token",
"--resource", "https://database.windows.net/",
"--query", "accessToken", "-o", "tsv"],
).decode().strip()

conn = dbapi.connect(driver="arpemssql", db_kwargs={
"adbc.arpemssql.server": "myserver.database.windows.net",
"adbc.arpemssql.database": "mydb",
"adbc.arpemssql.encrypt": "true",
"adbc.arpemssql.access_token": token,
})

2. Service principal (client credentials)​

The driver acquires the token itself; omit access_token:

Python
db_kwargs={
"adbc.arpemssql.server": "myserver.database.windows.net",
"adbc.arpemssql.database": "mydb",
"adbc.arpemssql.encrypt": "true",
"adbc.arpemssql.tenant_id": "<tenant-guid-or-domain>",
"adbc.arpemssql.client_id": "<app-client-id>",
"adbc.arpemssql.client_secret": "<secret>",
}

The service principal must be a database user (CREATE USER [<app>] FROM EXTERNAL PROVIDER). The token is acquired once per connection and refreshes on reconnect.

3. Managed identity​

On an Azure host (VM/VMSS via IMDS, or App Service / Functions / Container Apps), no secret is needed:

Python
db_kwargs={
"adbc.arpemssql.server": "myserver.database.windows.net",
"adbc.arpemssql.database": "mydb",
"adbc.arpemssql.encrypt": "true",
"adbc.arpemssql.managed_identity": "true", # or a user-assigned client id
}

4. Default credential chain​

auth_type=ActiveDirectoryDefault tries, in order: environment service principal (AZURE_TENANT_ID + AZURE_CLIENT_ID + AZURE_CLIENT_SECRET) → managed identity (short probe) → Azure CLI (az account get-access-token). Handy for code that runs unchanged on a dev machine, in CI, and on an Azure host:

Python
db_kwargs={
"adbc.arpemssql.server": "myserver.database.windows.net",
"adbc.arpemssql.database": "mydb",
"adbc.arpemssql.encrypt": "true",
"adbc.arpemssql.auth_type": "ActiveDirectoryDefault",
}

This is a practical subset of Azure's DefaultAzureCredential; workload-identity-file, Visual Studio, Azure PowerShell, and azd sources are not covered.


See also​