mssql-python 0.1.6__cp313-cp313-win_arm64.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.
Potentially problematic release.
This version of mssql-python might be problematic. Click here for more details.
- mssql_python/__init__.py +55 -0
- mssql_python/connection.py +424 -0
- mssql_python/constants.py +120 -0
- mssql_python/cursor.py +736 -0
- mssql_python/db_connection.py +38 -0
- mssql_python/ddbc_bindings.cp313-arm64.pyd +0 -0
- mssql_python/ddbc_bindings.py +38 -0
- mssql_python/exceptions.py +650 -0
- mssql_python/helpers.py +111 -0
- mssql_python/libs/LICENSING +19 -0
- mssql_python/libs/arm64/1033/msodbcsqlr18.rll +0 -0
- mssql_python/libs/arm64/msodbcdiag18.dll +0 -0
- mssql_python/libs/arm64/msodbcsql18.dll +0 -0
- mssql_python/libs/arm64/mssql-auth.dll +0 -0
- mssql_python/logging_config.py +65 -0
- mssql_python/mssql_python.pyi +192 -0
- mssql_python/msvcp140.dll +0 -0
- mssql_python/testing_ddbc_bindings.py +463 -0
- mssql_python/type.py +107 -0
- mssql_python-0.1.6.dist-info/METADATA +45 -0
- mssql_python-0.1.6.dist-info/RECORD +24 -0
- mssql_python-0.1.6.dist-info/WHEEL +5 -0
- mssql_python-0.1.6.dist-info/licenses/LICENSE +47 -0
- mssql_python-0.1.6.dist-info/top_level.txt +1 -0
mssql_python/helpers.py
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Copyright (c) Microsoft Corporation.
|
|
3
|
+
Licensed under the MIT license.
|
|
4
|
+
This module provides helper functions for the mssql_python package.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from mssql_python import ddbc_bindings
|
|
8
|
+
from mssql_python.exceptions import raise_exception
|
|
9
|
+
from mssql_python.logging_config import get_logger, ENABLE_LOGGING
|
|
10
|
+
|
|
11
|
+
logger = get_logger()
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def add_driver_to_connection_str(connection_str):
|
|
15
|
+
"""
|
|
16
|
+
Add the DDBC driver to the connection string if not present.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
connection_str (str): The original connection string.
|
|
20
|
+
|
|
21
|
+
Returns:
|
|
22
|
+
str: The connection string with the DDBC driver added.
|
|
23
|
+
|
|
24
|
+
Raises:
|
|
25
|
+
Exception: If the connection string is invalid.
|
|
26
|
+
"""
|
|
27
|
+
driver_name = "Driver={ODBC Driver 18 for SQL Server}"
|
|
28
|
+
try:
|
|
29
|
+
# Strip any leading or trailing whitespace from the connection string
|
|
30
|
+
connection_str = connection_str.strip()
|
|
31
|
+
connection_str = add_driver_name_to_app_parameter(connection_str)
|
|
32
|
+
|
|
33
|
+
# Split the connection string into individual attributes
|
|
34
|
+
connection_attributes = connection_str.split(";")
|
|
35
|
+
final_connection_attributes = []
|
|
36
|
+
|
|
37
|
+
# Iterate through the attributes and exclude any existing driver attribute
|
|
38
|
+
for attribute in connection_attributes:
|
|
39
|
+
if attribute.lower().split("=")[0] == "driver":
|
|
40
|
+
continue
|
|
41
|
+
final_connection_attributes.append(attribute)
|
|
42
|
+
|
|
43
|
+
# Join the remaining attributes back into a connection string
|
|
44
|
+
connection_str = ";".join(final_connection_attributes)
|
|
45
|
+
|
|
46
|
+
# Insert the driver attribute at the beginning of the connection string
|
|
47
|
+
final_connection_attributes.insert(0, driver_name)
|
|
48
|
+
connection_str = ";".join(final_connection_attributes)
|
|
49
|
+
|
|
50
|
+
except Exception as e:
|
|
51
|
+
raise Exception(
|
|
52
|
+
"Invalid connection string, Please follow the format: "
|
|
53
|
+
"Server=server_name;Database=database_name;UID=user_name;PWD=password"
|
|
54
|
+
) from e
|
|
55
|
+
|
|
56
|
+
return connection_str
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def check_error(handle_type, handle, ret):
|
|
60
|
+
"""
|
|
61
|
+
Check for errors and raise an exception if an error is found.
|
|
62
|
+
|
|
63
|
+
Args:
|
|
64
|
+
handle_type: The type of the handle (e.g., SQL_HANDLE_ENV, SQL_HANDLE_DBC).
|
|
65
|
+
handle: The SqlHandle object associated with the operation.
|
|
66
|
+
ret: The return code from the DDBC function call.
|
|
67
|
+
|
|
68
|
+
Raises:
|
|
69
|
+
RuntimeError: If an error is found.
|
|
70
|
+
"""
|
|
71
|
+
if ret < 0:
|
|
72
|
+
error_info = ddbc_bindings.DDBCSQLCheckError(handle_type, handle, ret)
|
|
73
|
+
if ENABLE_LOGGING:
|
|
74
|
+
logger.error("Error: %s", error_info.ddbcErrorMsg)
|
|
75
|
+
raise_exception(error_info.sqlState, error_info.ddbcErrorMsg)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def add_driver_name_to_app_parameter(connection_string):
|
|
79
|
+
"""
|
|
80
|
+
Modifies the input connection string by appending the APP name.
|
|
81
|
+
|
|
82
|
+
Args:
|
|
83
|
+
connection_string (str): The input connection string.
|
|
84
|
+
|
|
85
|
+
Returns:
|
|
86
|
+
str: The modified connection string.
|
|
87
|
+
"""
|
|
88
|
+
# Split the input string into key-value pairs
|
|
89
|
+
parameters = connection_string.split(";")
|
|
90
|
+
|
|
91
|
+
# Initialize variables
|
|
92
|
+
app_found = False
|
|
93
|
+
modified_parameters = []
|
|
94
|
+
|
|
95
|
+
# Iterate through the key-value pairs
|
|
96
|
+
for param in parameters:
|
|
97
|
+
if param.lower().startswith("app="):
|
|
98
|
+
# Overwrite the value with 'MSSQL-Python'
|
|
99
|
+
app_found = True
|
|
100
|
+
key, _ = param.split("=", 1)
|
|
101
|
+
modified_parameters.append(f"{key}=MSSQL-Python")
|
|
102
|
+
else:
|
|
103
|
+
# Keep other parameters as is
|
|
104
|
+
modified_parameters.append(param)
|
|
105
|
+
|
|
106
|
+
# If APP key is not found, append it
|
|
107
|
+
if not app_found:
|
|
108
|
+
modified_parameters.append("APP=MSSQL-Python")
|
|
109
|
+
|
|
110
|
+
# Join the parameters back into a connection string
|
|
111
|
+
return ";".join(modified_parameters) + ";"
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
A. The dynamic-link libraries (DLLs) in the mssql_python\libs\win folder fall under different Microsoft licenses.
|
|
2
|
+
====================================================================================================
|
|
3
|
+
Below is a breakdown of these components by their respective licenses.
|
|
4
|
+
|
|
5
|
+
1. Microsoft ODBC Driver 18 End User License Agreement (EULA)
|
|
6
|
+
These components are part of the Microsoft ODBC Driver 18 for SQL Server and are governed by the Microsoft ODBC Driver 18 EULA.
|
|
7
|
+
|
|
8
|
+
- msodbcsqlr18.rll – Resource library containing localized error messages for the ODBC driver.
|
|
9
|
+
- msodbcdiag18.dll – Diagnostic library for handling error reporting and troubleshooting.
|
|
10
|
+
- msodbcsql18.dll – Core ODBC driver enabling connectivity between SQL Server and applications.
|
|
11
|
+
|
|
12
|
+
For official licensing terms, refer to: mssql_python\libs\win\MICROSOFT_ODBC_DRIVER_FOR_SQL_SERVER_LICENSE.txt
|
|
13
|
+
|
|
14
|
+
2. Microsoft Visual C++ Redistributable EULA
|
|
15
|
+
These components are part of the Microsoft Visual C++ Redistributable and are governed by the Microsoft Visual C++ Redistributable EULA.
|
|
16
|
+
|
|
17
|
+
- msvcp140.dll – Microsoft C++ Standard Library runtime, required for running C++ applications.
|
|
18
|
+
|
|
19
|
+
For redistribution and usage terms, refer to: mssql_python\libs\win\MICROSOFT_VISUAL_STUDIO_LICENSE.txt
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Copyright (c) Microsoft Corporation.
|
|
3
|
+
Licensed under the MIT license.
|
|
4
|
+
This module provides logging configuration for the mssql_python package.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import logging
|
|
8
|
+
from logging.handlers import RotatingFileHandler
|
|
9
|
+
import os
|
|
10
|
+
import sys
|
|
11
|
+
|
|
12
|
+
ENABLE_LOGGING = False
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def setup_logging(mode="file", log_level=logging.DEBUG):
|
|
16
|
+
"""
|
|
17
|
+
Set up logging configuration.
|
|
18
|
+
|
|
19
|
+
This method configures the logging settings for the application.
|
|
20
|
+
It sets the log level, format, and log file location.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
mode (str): The logging mode ('file' or 'stdout').
|
|
24
|
+
log_level (int): The logging level (default: logging.DEBUG).
|
|
25
|
+
"""
|
|
26
|
+
global ENABLE_LOGGING
|
|
27
|
+
ENABLE_LOGGING = True
|
|
28
|
+
|
|
29
|
+
# Create a logger for mssql_python module
|
|
30
|
+
logger = logging.getLogger(__name__)
|
|
31
|
+
logger.setLevel(log_level)
|
|
32
|
+
|
|
33
|
+
# Construct the path to the log file
|
|
34
|
+
# TODO: Use a different dir to dump log file
|
|
35
|
+
current_dir = os.path.dirname(os.path.abspath(__file__))
|
|
36
|
+
log_file = os.path.join(current_dir, f'mssql_python_trace_{os.getpid()}.log')
|
|
37
|
+
|
|
38
|
+
# Create a log handler to log to driver specific file
|
|
39
|
+
# By default we only want to log to a file, max size 500MB, and keep 5 backups
|
|
40
|
+
# TODO: Rotate files based on time too? Ex: everyday
|
|
41
|
+
file_handler = RotatingFileHandler(log_file, maxBytes=512*1024*1024, backupCount=5)
|
|
42
|
+
file_handler.setLevel(log_level)
|
|
43
|
+
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(filename)s - %(message)s')
|
|
44
|
+
file_handler.setFormatter(formatter)
|
|
45
|
+
logger.addHandler(file_handler)
|
|
46
|
+
|
|
47
|
+
if mode == 'stdout':
|
|
48
|
+
# If the mode is stdout, then we want to log to the console as well
|
|
49
|
+
stdout_handler = logging.StreamHandler(sys.stdout)
|
|
50
|
+
stdout_handler.setLevel(log_level)
|
|
51
|
+
stdout_handler.setFormatter(formatter)
|
|
52
|
+
logger.addHandler(stdout_handler)
|
|
53
|
+
elif mode != 'file':
|
|
54
|
+
raise ValueError(f'Invalid logging mode: {mode}')
|
|
55
|
+
|
|
56
|
+
def get_logger():
|
|
57
|
+
"""
|
|
58
|
+
Get the logger instance.
|
|
59
|
+
|
|
60
|
+
Returns:
|
|
61
|
+
logging.Logger: The logger instance.
|
|
62
|
+
"""
|
|
63
|
+
if not ENABLE_LOGGING:
|
|
64
|
+
return None
|
|
65
|
+
return logging.getLogger(__name__)
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Copyright (c) Microsoft Corporation.
|
|
3
|
+
Licensed under the MIT license.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from typing import Final, Union
|
|
7
|
+
import datetime
|
|
8
|
+
|
|
9
|
+
# GLOBALS
|
|
10
|
+
# Read-Only
|
|
11
|
+
apilevel: Final[str] = "2.0"
|
|
12
|
+
paramstyle: Final[str] = "pyformat"
|
|
13
|
+
threadsafety: Final[int] = 1
|
|
14
|
+
|
|
15
|
+
# Type Objects
|
|
16
|
+
# https://www.python.org/dev/peps/pep-0249/#type-objects
|
|
17
|
+
class STRING:
|
|
18
|
+
"""
|
|
19
|
+
This type object is used to describe columns in a database that are string-based (e.g. CHAR).
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def __init__(self) -> None: ...
|
|
23
|
+
|
|
24
|
+
class BINARY:
|
|
25
|
+
"""
|
|
26
|
+
This type object is used to describe (long)
|
|
27
|
+
binary columns in a database (e.g. LONG, RAW, BLOBs).
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
def __init__(self) -> None: ...
|
|
31
|
+
|
|
32
|
+
class NUMBER:
|
|
33
|
+
"""
|
|
34
|
+
This type object is used to describe numeric columns in a database.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
def __init__(self) -> None: ...
|
|
38
|
+
|
|
39
|
+
class DATETIME:
|
|
40
|
+
"""
|
|
41
|
+
This type object is used to describe date/time columns in a database.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
def __init__(self) -> None: ...
|
|
45
|
+
|
|
46
|
+
class ROWID:
|
|
47
|
+
"""
|
|
48
|
+
This type object is used to describe the “Row ID” column in a database.
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
def __init__(self) -> None: ...
|
|
52
|
+
|
|
53
|
+
# Type Constructors
|
|
54
|
+
def Date(year: int, month: int, day: int) -> datetime.date: ...
|
|
55
|
+
def Time(hour: int, minute: int, second: int) -> datetime.time: ...
|
|
56
|
+
def Timestamp(
|
|
57
|
+
year: int, month: int, day: int, hour: int, minute: int, second: int, microsecond: int
|
|
58
|
+
) -> datetime.datetime: ...
|
|
59
|
+
def DateFromTicks(ticks: int) -> datetime.date: ...
|
|
60
|
+
def TimeFromTicks(ticks: int) -> datetime.time: ...
|
|
61
|
+
def TimestampFromTicks(ticks: int) -> datetime.datetime: ...
|
|
62
|
+
def Binary(string: str) -> bytes: ...
|
|
63
|
+
|
|
64
|
+
# Exceptions
|
|
65
|
+
# https://www.python.org/dev/peps/pep-0249/#exceptions
|
|
66
|
+
class Warning(Exception): ...
|
|
67
|
+
class Error(Exception): ...
|
|
68
|
+
class InterfaceError(Error): ...
|
|
69
|
+
class DatabaseError(Error): ...
|
|
70
|
+
class DataError(DatabaseError): ...
|
|
71
|
+
class OperationalError(DatabaseError): ...
|
|
72
|
+
class IntegrityError(DatabaseError): ...
|
|
73
|
+
class InternalError(DatabaseError): ...
|
|
74
|
+
class ProgrammingError(DatabaseError): ...
|
|
75
|
+
class NotSupportedError(DatabaseError): ...
|
|
76
|
+
|
|
77
|
+
# Connection Objects
|
|
78
|
+
class Connection:
|
|
79
|
+
"""
|
|
80
|
+
Connection object for interacting with the database.
|
|
81
|
+
|
|
82
|
+
https://www.python.org/dev/peps/pep-0249/#connection-objects
|
|
83
|
+
|
|
84
|
+
This class should not be instantiated directly, instead call global connect() method to
|
|
85
|
+
create a Connection object.
|
|
86
|
+
"""
|
|
87
|
+
|
|
88
|
+
def cursor(self) -> "Cursor":
|
|
89
|
+
"""
|
|
90
|
+
Return a new Cursor object using the connection.
|
|
91
|
+
"""
|
|
92
|
+
...
|
|
93
|
+
|
|
94
|
+
def commit(self) -> None:
|
|
95
|
+
"""
|
|
96
|
+
Commit the current transaction.
|
|
97
|
+
"""
|
|
98
|
+
...
|
|
99
|
+
|
|
100
|
+
def rollback(self) -> None:
|
|
101
|
+
"""
|
|
102
|
+
Roll back the current transaction.
|
|
103
|
+
"""
|
|
104
|
+
...
|
|
105
|
+
|
|
106
|
+
def close(self) -> None:
|
|
107
|
+
"""
|
|
108
|
+
Close the connection now.
|
|
109
|
+
"""
|
|
110
|
+
...
|
|
111
|
+
|
|
112
|
+
# Cursor Objects
|
|
113
|
+
class Cursor:
|
|
114
|
+
"""
|
|
115
|
+
Cursor object for executing SQL queries and fetching results.
|
|
116
|
+
|
|
117
|
+
https://www.python.org/dev/peps/pep-0249/#cursor-objects
|
|
118
|
+
|
|
119
|
+
This class should not be instantiated directly, instead call cursor() from a Connection
|
|
120
|
+
object to create a Cursor object.
|
|
121
|
+
"""
|
|
122
|
+
|
|
123
|
+
def callproc(
|
|
124
|
+
self, procname: str, parameters: Union[None, list] = None
|
|
125
|
+
) -> Union[None, list]:
|
|
126
|
+
"""
|
|
127
|
+
Call a stored database procedure with the given name.
|
|
128
|
+
"""
|
|
129
|
+
...
|
|
130
|
+
|
|
131
|
+
def close(self) -> None:
|
|
132
|
+
"""
|
|
133
|
+
Close the cursor now.
|
|
134
|
+
"""
|
|
135
|
+
...
|
|
136
|
+
|
|
137
|
+
def execute(
|
|
138
|
+
self, operation: str, parameters: Union[None, list, dict] = None
|
|
139
|
+
) -> None:
|
|
140
|
+
"""
|
|
141
|
+
Prepare and execute a database operation (query or command).
|
|
142
|
+
"""
|
|
143
|
+
...
|
|
144
|
+
|
|
145
|
+
def executemany(self, operation: str, seq_of_parameters: list) -> None:
|
|
146
|
+
"""
|
|
147
|
+
Prepare a database operation and execute it against all parameter sequences.
|
|
148
|
+
"""
|
|
149
|
+
...
|
|
150
|
+
|
|
151
|
+
def fetchone(self) -> Union[None, tuple]:
|
|
152
|
+
"""
|
|
153
|
+
Fetch the next row of a query result set.
|
|
154
|
+
"""
|
|
155
|
+
...
|
|
156
|
+
|
|
157
|
+
def fetchmany(self, size: int = None) -> list:
|
|
158
|
+
"""
|
|
159
|
+
Fetch the next set of rows of a query result.
|
|
160
|
+
"""
|
|
161
|
+
...
|
|
162
|
+
|
|
163
|
+
def fetchall(self) -> list:
|
|
164
|
+
"""
|
|
165
|
+
Fetch all (remaining) rows of a query result.
|
|
166
|
+
"""
|
|
167
|
+
...
|
|
168
|
+
|
|
169
|
+
def nextset(self) -> Union[None, bool]:
|
|
170
|
+
"""
|
|
171
|
+
Skip to the next available result set.
|
|
172
|
+
"""
|
|
173
|
+
...
|
|
174
|
+
|
|
175
|
+
def setinputsizes(self, sizes: list) -> None:
|
|
176
|
+
"""
|
|
177
|
+
Predefine memory areas for the operation’s parameters.
|
|
178
|
+
"""
|
|
179
|
+
...
|
|
180
|
+
|
|
181
|
+
def setoutputsize(self, size: int, column: int = None) -> None:
|
|
182
|
+
"""
|
|
183
|
+
Set a column buffer size for fetches of large columns.
|
|
184
|
+
"""
|
|
185
|
+
...
|
|
186
|
+
|
|
187
|
+
# Module Functions
|
|
188
|
+
def connect(connection_str: str) -> Connection:
|
|
189
|
+
"""
|
|
190
|
+
Constructor for creating a connection to the database.
|
|
191
|
+
"""
|
|
192
|
+
...
|
|
Binary file
|