mssql-python 1.16.0__cp315-cp315-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mssql_python/__init__.py +662 -0
- mssql_python/async_query/__init__.py +40 -0
- mssql_python/async_query/_connection_context.py +39 -0
- mssql_python/async_query/_native.py +23 -0
- mssql_python/async_query/async_connection.py +160 -0
- mssql_python/async_query/async_cursor.py +230 -0
- mssql_python/async_query/async_execute.py +115 -0
- mssql_python/async_query/async_fetch.py +134 -0
- mssql_python/async_query/exception_translator.py +114 -0
- mssql_python/auth.py +913 -0
- mssql_python/connection.py +2357 -0
- mssql_python/connection_string_builder.py +114 -0
- mssql_python/connection_string_parser.py +424 -0
- mssql_python/constants.py +701 -0
- mssql_python/cursor.py +4188 -0
- mssql_python/db_connection.py +98 -0
- mssql_python/ddbc_bindings.cp315-amd64.pyd +0 -0
- mssql_python/ddbc_bindings.py +215 -0
- mssql_python/decimal_config.py +114 -0
- mssql_python/exceptions.py +588 -0
- mssql_python/helpers.py +416 -0
- mssql_python/logging.py +714 -0
- mssql_python/mssql_python.pyi +481 -0
- mssql_python/msvcp140.dll +0 -0
- mssql_python/odbc_provider.py +251 -0
- mssql_python/parameter_helper.py +488 -0
- mssql_python/perf_timer.py +286 -0
- mssql_python/pooling.py +151 -0
- mssql_python/py.typed +1 -0
- mssql_python/row.py +398 -0
- mssql_python/type.py +160 -0
- mssql_python-1.16.0.dist-info/METADATA +102 -0
- mssql_python-1.16.0.dist-info/RECORD +36 -0
- mssql_python-1.16.0.dist-info/WHEEL +5 -0
- mssql_python-1.16.0.dist-info/licenses/LICENSE +47 -0
- mssql_python-1.16.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Copyright (c) Microsoft Corporation.
|
|
3
|
+
Licensed under the MIT license.
|
|
4
|
+
This module provides a way to create a new connection object to interact with the database.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Any, Dict, Optional, Union
|
|
8
|
+
|
|
9
|
+
from mssql_python.connection import Connection, TokenProvider
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def connect(
|
|
13
|
+
connection_str: str = "",
|
|
14
|
+
autocommit: bool = False,
|
|
15
|
+
attrs_before: Optional[Dict[int, Union[int, str, bytes]]] = None,
|
|
16
|
+
timeout: int = 0,
|
|
17
|
+
native_uuid: Optional[bool] = None,
|
|
18
|
+
token_provider: Optional[TokenProvider] = None,
|
|
19
|
+
**kwargs: Any,
|
|
20
|
+
) -> Connection:
|
|
21
|
+
"""
|
|
22
|
+
Constructor for creating a connection to the database.
|
|
23
|
+
|
|
24
|
+
Args:
|
|
25
|
+
connection_str (str): The connection string to connect to.
|
|
26
|
+
autocommit (bool): If True, causes a commit to be performed after each SQL statement.
|
|
27
|
+
attrs_before (dict, optional): A dictionary of connection attributes to set before
|
|
28
|
+
connecting.
|
|
29
|
+
timeout (int): Login (connection-attempt) timeout in seconds. 0 (default)
|
|
30
|
+
uses the driver default. This bounds the login/network handshake (via
|
|
31
|
+
SQL_ATTR_LOGIN_TIMEOUT), not query execution — it is distinct from the
|
|
32
|
+
``Connection.timeout`` property, which is the per-statement query
|
|
33
|
+
timeout. If both ``timeout`` and ``attrs_before[SQL_ATTR_LOGIN_TIMEOUT]``
|
|
34
|
+
are supplied, the explicit ``attrs_before`` value takes precedence.
|
|
35
|
+
native_uuid (bool, optional): Controls whether UNIQUEIDENTIFIER columns return
|
|
36
|
+
uuid.UUID objects (True) or str (False) for this connection.
|
|
37
|
+
- True: UNIQUEIDENTIFIER columns return uuid.UUID objects.
|
|
38
|
+
- False: UNIQUEIDENTIFIER columns return str (pyodbc-compatible).
|
|
39
|
+
- None (default): Uses the module-level ``mssql_python.native_uuid`` setting (True).
|
|
40
|
+
|
|
41
|
+
This per-connection override is useful for migration from pyodbc:
|
|
42
|
+
connections that need string UUIDs can pass native_uuid=False, while the default (True)
|
|
43
|
+
returns native uuid.UUID objects.
|
|
44
|
+
token_provider (object, optional): A token provider for Microsoft Entra ID
|
|
45
|
+
authentication. This must be any object with a ``.get_token(scope)`` method that
|
|
46
|
+
returns an object with a ``.token`` attribute containing a raw JWT string — for
|
|
47
|
+
example, any ``azure-identity`` credential class such as
|
|
48
|
+
``DefaultAzureCredential``, ``AzureCliCredential``, ``ManagedIdentityCredential``,
|
|
49
|
+
``CertificateCredential``, etc.
|
|
50
|
+
|
|
51
|
+
When provided, the driver calls ``token_provider.get_token()`` to acquire an
|
|
52
|
+
access token for SQL Server, bypassing the built-in credential map.
|
|
53
|
+
Cannot be combined with ``Authentication=`` in the connection string.
|
|
54
|
+
|
|
55
|
+
For environment-portable code, prefer ``Authentication=ActiveDirectoryDefault``
|
|
56
|
+
in the connection string — ``DefaultAzureCredential`` automatically picks the
|
|
57
|
+
right credential per environment (CLI on dev, Managed Identity in prod).
|
|
58
|
+
Use ``token_provider=`` only when you need explicit control over token
|
|
59
|
+
acquisition (e.g., excluding specific providers, using a credential not in
|
|
60
|
+
the built-in map, or passing custom options to the credential constructor).
|
|
61
|
+
|
|
62
|
+
Example::
|
|
63
|
+
|
|
64
|
+
from azure.identity import AzureCliCredential
|
|
65
|
+
conn = mssql_python.connect("Server=s;Database=d",
|
|
66
|
+
token_provider=AzureCliCredential())
|
|
67
|
+
|
|
68
|
+
Note: the token scope is fixed to the Azure **commercial** cloud
|
|
69
|
+
(``https://database.windows.net/.default``). Sovereign clouds (Azure US
|
|
70
|
+
Government, Azure China, Azure Germany) are **out of scope** — acquire the token
|
|
71
|
+
yourself and pass it via ``attrs_before[SQL_COPT_SS_ACCESS_TOKEN]`` instead.
|
|
72
|
+
Keyword Args:
|
|
73
|
+
**kwargs: Additional key/value pairs for the connection string.
|
|
74
|
+
Below attributes are not implemented in the internal driver:
|
|
75
|
+
- encoding (str): The encoding for the connection string.
|
|
76
|
+
- ansi (bool): If True, indicates the driver does not support Unicode.
|
|
77
|
+
|
|
78
|
+
Returns:
|
|
79
|
+
Connection: A new connection object to interact with the database.
|
|
80
|
+
|
|
81
|
+
Raises:
|
|
82
|
+
DatabaseError: If there is an error while trying to connect to the database.
|
|
83
|
+
InterfaceError: If there is an error related to the database interface.
|
|
84
|
+
|
|
85
|
+
This function provides a way to create a new connection object, which can then
|
|
86
|
+
be used to perform database operations such as executing queries, committing
|
|
87
|
+
transactions, and closing the connection.
|
|
88
|
+
"""
|
|
89
|
+
conn = Connection(
|
|
90
|
+
connection_str,
|
|
91
|
+
autocommit=autocommit,
|
|
92
|
+
attrs_before=attrs_before,
|
|
93
|
+
timeout=timeout,
|
|
94
|
+
native_uuid=native_uuid,
|
|
95
|
+
token_provider=token_provider,
|
|
96
|
+
**kwargs,
|
|
97
|
+
)
|
|
98
|
+
return conn
|
|
Binary file
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Dynamic loading of platform-specific DDBC bindings for mssql-python.
|
|
3
|
+
|
|
4
|
+
This module handles the runtime loading of the appropriate compiled extension
|
|
5
|
+
module based on the current platform, architecture, and Python version.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
import importlib.util
|
|
10
|
+
import sys
|
|
11
|
+
import platform
|
|
12
|
+
import sysconfig
|
|
13
|
+
import warnings
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def normalize_architecture(platform_name_param, architecture_param):
|
|
17
|
+
"""
|
|
18
|
+
Normalize architecture names for the given platform.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
platform_name_param (str): Platform name ('windows', 'darwin', 'linux')
|
|
22
|
+
architecture_param (str): Architecture string to normalize
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
str: Normalized architecture name
|
|
26
|
+
|
|
27
|
+
Raises:
|
|
28
|
+
ImportError: If architecture is not supported for the given platform
|
|
29
|
+
OSError: If platform is not supported
|
|
30
|
+
"""
|
|
31
|
+
arch_lower = architecture_param.lower()
|
|
32
|
+
|
|
33
|
+
if platform_name_param == "windows":
|
|
34
|
+
arch_map = {
|
|
35
|
+
"win64": "x64",
|
|
36
|
+
"amd64": "x64",
|
|
37
|
+
"x64": "x64",
|
|
38
|
+
"win32": "x86",
|
|
39
|
+
"x86": "x86",
|
|
40
|
+
"arm64": "arm64",
|
|
41
|
+
}
|
|
42
|
+
if arch_lower in arch_map:
|
|
43
|
+
return arch_map[arch_lower]
|
|
44
|
+
supported = list(set(arch_map.keys()))
|
|
45
|
+
raise ImportError(
|
|
46
|
+
f"Unsupported architecture '{architecture_param}' for platform "
|
|
47
|
+
f"'{platform_name_param}'; expected one of {supported}"
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
if platform_name_param == "darwin":
|
|
51
|
+
# For macOS, return runtime architecture
|
|
52
|
+
return platform.machine().lower()
|
|
53
|
+
|
|
54
|
+
if platform_name_param == "linux":
|
|
55
|
+
arch_map = {
|
|
56
|
+
"x64": "x86_64",
|
|
57
|
+
"amd64": "x86_64",
|
|
58
|
+
"x86_64": "x86_64",
|
|
59
|
+
"arm64": "arm64",
|
|
60
|
+
"aarch64": "arm64",
|
|
61
|
+
}
|
|
62
|
+
if arch_lower in arch_map:
|
|
63
|
+
return arch_map[arch_lower]
|
|
64
|
+
supported = list(set(arch_map.keys()))
|
|
65
|
+
raise ImportError(
|
|
66
|
+
f"Unsupported architecture '{architecture_param}' for platform "
|
|
67
|
+
f"'{platform_name_param}'; expected one of {supported}"
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
supported_platforms_list = ["windows", "darwin", "linux"]
|
|
71
|
+
raise OSError(
|
|
72
|
+
f"Unsupported platform '{platform_name_param}'; expected one of "
|
|
73
|
+
f"{supported_platforms_list}"
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def get_interpreter_architecture(platform_name_param):
|
|
78
|
+
"""
|
|
79
|
+
Get the raw architecture string of the running interpreter.
|
|
80
|
+
|
|
81
|
+
On Windows, ``platform.machine()`` reports the host CPU rather than the
|
|
82
|
+
architecture the interpreter was built for. The two differ when an x64
|
|
83
|
+
interpreter runs emulated on a Windows ARM64 machine (the python.org
|
|
84
|
+
"64-bit" installer is x64), so the loader would look for an arm64 binary
|
|
85
|
+
that the installed win_amd64 wheel never shipped. ``sysconfig.get_platform()``
|
|
86
|
+
is derived from the interpreter build and matches the wheel tag, so it is
|
|
87
|
+
the source of truth on Windows.
|
|
88
|
+
|
|
89
|
+
Args:
|
|
90
|
+
platform_name_param (str): Platform name ('windows', 'darwin', 'linux')
|
|
91
|
+
|
|
92
|
+
Returns:
|
|
93
|
+
str: Lower case architecture string accepted by normalize_architecture()
|
|
94
|
+
"""
|
|
95
|
+
if platform_name_param == "windows":
|
|
96
|
+
# 'win-amd64' -> 'amd64', 'win-arm64' -> 'arm64', 'win32' -> 'win32'
|
|
97
|
+
return sysconfig.get_platform().lower().removeprefix("win-")
|
|
98
|
+
return platform.machine().lower()
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def get_module_architecture(platform_name_param):
|
|
102
|
+
"""
|
|
103
|
+
Get the architecture token used in the compiled ddbc_bindings filename.
|
|
104
|
+
|
|
105
|
+
Args:
|
|
106
|
+
platform_name_param (str): Platform name ('windows', 'darwin', 'linux')
|
|
107
|
+
|
|
108
|
+
Returns:
|
|
109
|
+
str: 'universal2' on macOS, otherwise the normalized architecture with
|
|
110
|
+
the Windows x64 build renamed to 'amd64' and the Windows x86 build
|
|
111
|
+
renamed to 'win32', matching the file names the build produces
|
|
112
|
+
"""
|
|
113
|
+
# Special handling for macOS universal2 binaries
|
|
114
|
+
if platform_name_param == "darwin":
|
|
115
|
+
return "universal2"
|
|
116
|
+
|
|
117
|
+
architecture_name = normalize_architecture(
|
|
118
|
+
platform_name_param, get_interpreter_architecture(platform_name_param)
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
# Handle Windows-specific naming for binary files. The build names the
|
|
122
|
+
# x64 artifact 'amd64' and the x86 artifact 'win32' (see pybind/build.bat
|
|
123
|
+
# and pybind/CMakeLists.txt), so the loader has to look for those tokens.
|
|
124
|
+
if platform_name_param == "windows" and architecture_name == "x64":
|
|
125
|
+
architecture_name = "amd64"
|
|
126
|
+
elif platform_name_param == "windows" and architecture_name == "x86":
|
|
127
|
+
architecture_name = "win32"
|
|
128
|
+
return architecture_name
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
def find_module_path(module_dir_param, python_version_param, architecture_param, extension_param):
|
|
132
|
+
"""
|
|
133
|
+
Find the compiled ddbc_bindings module file for the running interpreter.
|
|
134
|
+
|
|
135
|
+
Args:
|
|
136
|
+
module_dir_param (str): Directory that contains the compiled module
|
|
137
|
+
python_version_param (str): Python version tag such as 'cp312'
|
|
138
|
+
architecture_param (str): Architecture token from get_module_architecture()
|
|
139
|
+
extension_param (str): File extension, '.pyd' on Windows and '.so' elsewhere
|
|
140
|
+
|
|
141
|
+
Returns:
|
|
142
|
+
str: Path of the exactly matching module file. If it does not exist, the
|
|
143
|
+
first ddbc_bindings file built for this interpreter's version tag is
|
|
144
|
+
returned instead and a RuntimeWarning is emitted.
|
|
145
|
+
|
|
146
|
+
Raises:
|
|
147
|
+
ImportError: If no ddbc_bindings file for this interpreter's version
|
|
148
|
+
tag exists with the right extension
|
|
149
|
+
"""
|
|
150
|
+
expected_module = f"ddbc_bindings.{python_version_param}-{architecture_param}{extension_param}"
|
|
151
|
+
module_path_found = os.path.join(module_dir_param, expected_module)
|
|
152
|
+
|
|
153
|
+
if os.path.exists(module_path_found):
|
|
154
|
+
return module_path_found
|
|
155
|
+
|
|
156
|
+
# Fallback: only binaries built for this interpreter's version tag are
|
|
157
|
+
# loadable, since the cpXY tags are version specific rather than abi3. A
|
|
158
|
+
# different architecture may still work (for example a universal2 build),
|
|
159
|
+
# but a different Python version fails later inside importlib with a
|
|
160
|
+
# confusing DLL or symbol error, so it is excluded here. Sorted so the
|
|
161
|
+
# pick is deterministic when several candidates remain.
|
|
162
|
+
module_files = sorted(
|
|
163
|
+
f
|
|
164
|
+
for f in os.listdir(module_dir_param)
|
|
165
|
+
if f.startswith(f"ddbc_bindings.{python_version_param}-") and f.endswith(extension_param)
|
|
166
|
+
)
|
|
167
|
+
if not module_files:
|
|
168
|
+
raise ImportError(
|
|
169
|
+
f"No ddbc_bindings module found for {python_version_param}-{architecture_param} "
|
|
170
|
+
f"with extension {extension_param}"
|
|
171
|
+
)
|
|
172
|
+
warnings.warn(
|
|
173
|
+
f"Using fallback module file {module_files[0]} instead of {expected_module}",
|
|
174
|
+
RuntimeWarning,
|
|
175
|
+
stacklevel=2,
|
|
176
|
+
)
|
|
177
|
+
return os.path.join(module_dir_param, module_files[0])
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
# Get current Python version and architecture
|
|
181
|
+
python_version = f"cp{sys.version_info.major}{sys.version_info.minor}"
|
|
182
|
+
|
|
183
|
+
platform_name = platform.system().lower()
|
|
184
|
+
architecture = get_module_architecture(platform_name)
|
|
185
|
+
|
|
186
|
+
# Validate supported platforms
|
|
187
|
+
if platform_name not in ["windows", "darwin", "linux"]:
|
|
188
|
+
supported_platforms = ["windows", "darwin", "linux"]
|
|
189
|
+
raise ImportError(
|
|
190
|
+
f"Unsupported platform '{platform_name}' for mssql-python; expected one "
|
|
191
|
+
f"of {supported_platforms}"
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
# Determine extension based on platform
|
|
195
|
+
if platform_name == "windows":
|
|
196
|
+
extension = ".pyd"
|
|
197
|
+
else: # macOS or Linux
|
|
198
|
+
extension = ".so"
|
|
199
|
+
|
|
200
|
+
# Find the specifically matching module file
|
|
201
|
+
module_dir = os.path.dirname(__file__)
|
|
202
|
+
module_path = find_module_path(module_dir, python_version, architecture, extension)
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
# Use the original module name 'ddbc_bindings' that the C extension was compiled with
|
|
206
|
+
module_name = "ddbc_bindings"
|
|
207
|
+
spec = importlib.util.spec_from_file_location(module_name, module_path)
|
|
208
|
+
module = importlib.util.module_from_spec(spec)
|
|
209
|
+
sys.modules[module_name] = module
|
|
210
|
+
spec.loader.exec_module(module)
|
|
211
|
+
|
|
212
|
+
# Copy all attributes from the loaded module to this module
|
|
213
|
+
for attr in dir(module):
|
|
214
|
+
if not attr.startswith("__"):
|
|
215
|
+
globals()[attr] = getattr(module, attr)
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Copyright (c) Microsoft Corporation.
|
|
3
|
+
Licensed under the MIT license.
|
|
4
|
+
|
|
5
|
+
This module provides functions for managing decimal separator configuration.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import TYPE_CHECKING
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING: # pragma: no cover
|
|
11
|
+
from mssql_python.helpers import Settings
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _setDecimalSeparator(separator: str, settings: "Settings", set_in_cpp_func=None) -> None:
|
|
15
|
+
"""
|
|
16
|
+
Internal implementation for setting the decimal separator.
|
|
17
|
+
|
|
18
|
+
Not intended for direct external use — the public API is exposed via
|
|
19
|
+
``mssql_python.setDecimalSeparator`` (created by ``create_decimal_separator_functions``).
|
|
20
|
+
|
|
21
|
+
Args:
|
|
22
|
+
separator (str): The character to use as decimal separator
|
|
23
|
+
settings (Settings): The settings object to update
|
|
24
|
+
set_in_cpp_func: Optional callable to set the separator in C++ bindings
|
|
25
|
+
|
|
26
|
+
Raises:
|
|
27
|
+
ValueError: If the separator is not a single character string
|
|
28
|
+
"""
|
|
29
|
+
# Type validation
|
|
30
|
+
if not isinstance(separator, str):
|
|
31
|
+
raise ValueError("Decimal separator must be a string")
|
|
32
|
+
|
|
33
|
+
# Length validation
|
|
34
|
+
if len(separator) == 0:
|
|
35
|
+
raise ValueError("Decimal separator cannot be empty")
|
|
36
|
+
|
|
37
|
+
if len(separator) > 1:
|
|
38
|
+
raise ValueError("Decimal separator must be a single character")
|
|
39
|
+
|
|
40
|
+
# Character validation (covers \t, \n, \r, \v, \f and all other whitespace)
|
|
41
|
+
if separator.isspace():
|
|
42
|
+
raise ValueError("Whitespace characters are not allowed as decimal separators")
|
|
43
|
+
|
|
44
|
+
# Set in Python side settings
|
|
45
|
+
settings.decimal_separator = separator
|
|
46
|
+
|
|
47
|
+
# Update the C++ side if available
|
|
48
|
+
if set_in_cpp_func is not None:
|
|
49
|
+
set_in_cpp_func(separator)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _getDecimalSeparator(settings: "Settings") -> str:
|
|
53
|
+
"""
|
|
54
|
+
Internal implementation for getting the decimal separator.
|
|
55
|
+
|
|
56
|
+
Not intended for direct external use — the public API is exposed via
|
|
57
|
+
``mssql_python.getDecimalSeparator`` (created by ``create_decimal_separator_functions``).
|
|
58
|
+
|
|
59
|
+
Args:
|
|
60
|
+
settings (Settings): The settings object to read from
|
|
61
|
+
|
|
62
|
+
Returns:
|
|
63
|
+
str: The current decimal separator character
|
|
64
|
+
"""
|
|
65
|
+
return settings.decimal_separator
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def create_decimal_separator_functions(settings: "Settings"):
|
|
69
|
+
"""
|
|
70
|
+
Factory function to create decimal separator getter/setter bound to specific settings.
|
|
71
|
+
|
|
72
|
+
This function handles importing the C++ binding and initializing the decimal separator.
|
|
73
|
+
|
|
74
|
+
Args:
|
|
75
|
+
settings: The Settings instance to bind to
|
|
76
|
+
|
|
77
|
+
Returns:
|
|
78
|
+
Tuple of (setDecimalSeparator, getDecimalSeparator) functions
|
|
79
|
+
"""
|
|
80
|
+
# Try to import and initialize the C++ binding
|
|
81
|
+
try:
|
|
82
|
+
from mssql_python.ddbc_bindings import DDBCSetDecimalSeparator
|
|
83
|
+
|
|
84
|
+
# Set the initial decimal separator in C++
|
|
85
|
+
DDBCSetDecimalSeparator(settings.decimal_separator)
|
|
86
|
+
cpp_binding = DDBCSetDecimalSeparator
|
|
87
|
+
except ImportError:
|
|
88
|
+
# Handle case where ddbc_bindings is not available
|
|
89
|
+
cpp_binding = None
|
|
90
|
+
|
|
91
|
+
def setter(separator: str) -> None:
|
|
92
|
+
"""
|
|
93
|
+
Sets the decimal separator character used when parsing NUMERIC/DECIMAL values
|
|
94
|
+
from the database, e.g. the "." in "1,234.56".
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
separator (str): The character to use as decimal separator
|
|
98
|
+
|
|
99
|
+
Raises:
|
|
100
|
+
ValueError: If the separator is not a single character string
|
|
101
|
+
"""
|
|
102
|
+
_setDecimalSeparator(separator, settings, cpp_binding)
|
|
103
|
+
|
|
104
|
+
def getter() -> str:
|
|
105
|
+
"""
|
|
106
|
+
Returns the decimal separator character used when parsing NUMERIC/DECIMAL values
|
|
107
|
+
from the database.
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
str: The current decimal separator character
|
|
111
|
+
"""
|
|
112
|
+
return _getDecimalSeparator(settings)
|
|
113
|
+
|
|
114
|
+
return setter, getter
|