Skip to content

Commit 2b521e9

Browse files
committed
Added Build steps and Backward compatibility
1 parent d2b82b5 commit 2b521e9

40 files changed

Lines changed: 968 additions & 403 deletions

.gitignore

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ mssql_python/pybind/build/
33

44
mssql_python/pybind/pymsbuild/build/
55

6-
# Ignore all pyd files
7-
**.pyd
6+
# Ignore pyd file
7+
mssql_python/ddbc_bindings.pyd
88

99
# Ignore pycache files and folders
1010
__pycache__/
@@ -26,11 +26,25 @@ mssql_python/.vs
2626
test-*.xml
2727
**/test-**.xml
2828

29-
# Ignore coverage files
30-
coverage.xml
31-
.coverage
32-
.coverage.*
33-
3429
# Ignore the build & mssql_python.egg-info directories
3530
build/
36-
mssql_python.egg-info/
31+
mssql_python.egg-info/
32+
33+
# Python bytecode
34+
__pycache__/
35+
*.py[cod]
36+
*$py.class
37+
38+
# Distribution / packaging
39+
dist/
40+
build/
41+
*.egg-info/
42+
43+
# C extensions
44+
*.so
45+
*.pyd
46+
47+
# IDE files
48+
.vscode/
49+
.idea/
50+
*.swp
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
# Pipeline name shown in ADO UI
2+
name: build-whl-pipeline
3+
4+
# Trigger the pipeline on pushes to these branches
5+
trigger:
6+
branches:
7+
include:
8+
- main
9+
- dev
10+
11+
# Use Microsoft-hosted Windows VM
12+
pool:
13+
vmImage: 'windows-latest'
14+
15+
jobs:
16+
- job: BuildPYDs
17+
displayName: 'Build PYD -'
18+
# Strategy matrix to build all combinations
19+
strategy:
20+
matrix:
21+
# Python 3.9
22+
py39_x64:
23+
pythonVersion: '3.9' # Host Python version
24+
shortPyVer: '39' # Used in filenames like cp39
25+
architecture: 'x64' # Host Python architecture
26+
targetArch: 'x64' # Target architecture to pass to build.bat
27+
py39_x86:
28+
pythonVersion: '3.9'
29+
shortPyVer: '39'
30+
architecture: 'x86'
31+
targetArch: 'x86'
32+
py39_arm64:
33+
pythonVersion: '3.9'
34+
shortPyVer: '39'
35+
architecture: 'x64' # No arm64 Python, use x64 host
36+
targetArch: 'arm64'
37+
38+
# Python 3.10
39+
py310_x64:
40+
pythonVersion: '3.10' # Host Python version
41+
shortPyVer: '310' # Used in filenames like cp310
42+
architecture: 'x64' # Host Python architecture
43+
targetArch: 'x64' # Target architecture to pass to build.bat
44+
py310_x86:
45+
pythonVersion: '3.10'
46+
shortPyVer: '310'
47+
architecture: 'x86'
48+
targetArch: 'x86'
49+
py310_arm64:
50+
pythonVersion: '3.10'
51+
shortPyVer: '310'
52+
architecture: 'x64' # No arm64 Python, use x64 host
53+
targetArch: 'arm64'
54+
55+
# Python 3.11
56+
py311_x64:
57+
pythonVersion: '3.11' # Host Python version
58+
shortPyVer: '311' # Used in filenames like cp311
59+
architecture: 'x64' # Host Python architecture
60+
targetArch: 'x64' # Target architecture to pass to build.bat
61+
py311_x86:
62+
pythonVersion: '3.11'
63+
shortPyVer: '311'
64+
architecture: 'x86'
65+
targetArch: 'x86'
66+
py311_arm64:
67+
pythonVersion: '3.11'
68+
shortPyVer: '311'
69+
architecture: 'x64' # No arm64 Python, use x64 host
70+
targetArch: 'arm64'
71+
72+
# Python 3.12
73+
py312_x64:
74+
pythonVersion: '3.12'
75+
shortPyVer: '312'
76+
architecture: 'x64'
77+
targetArch: 'x64'
78+
py312_x86:
79+
pythonVersion: '3.12'
80+
shortPyVer: '312'
81+
architecture: 'x86'
82+
targetArch: 'x86'
83+
py312_arm64:
84+
pythonVersion: '3.12'
85+
shortPyVer: '312'
86+
architecture: 'x64'
87+
targetArch: 'arm64'
88+
89+
# Python 3.13
90+
py313_x64:
91+
pythonVersion: '3.13'
92+
shortPyVer: '313'
93+
architecture: 'x64'
94+
targetArch: 'x64'
95+
py313_x86:
96+
pythonVersion: '3.13'
97+
shortPyVer: '313'
98+
architecture: 'x86'
99+
targetArch: 'x86'
100+
py313_arm64:
101+
pythonVersion: '3.13'
102+
shortPyVer: '313'
103+
architecture: 'x64'
104+
targetArch: 'arm64'
105+
106+
steps:
107+
# Use correct Python version and architecture for the current job
108+
- task: UsePythonVersion@0
109+
inputs:
110+
versionSpec: '$(pythonVersion)'
111+
architecture: '$(architecture)'
112+
addToPath: true
113+
displayName: 'Use Python $(pythonVersion) ($(architecture))'
114+
115+
# Install required packages: pip, CMake, pybind11
116+
- script: |
117+
python -m pip install --upgrade pip
118+
pip install -r requirements.txt
119+
pip install cmake pybind11
120+
displayName: 'Install dependencies'
121+
122+
# Build the PYD file by calling build.bat
123+
- script: |
124+
echo "Python Version: $(pythonVersion)"
125+
echo "Short Tag: $(shortPyVer)"
126+
echo "Architecture: Host=$(architecture), Target=$(targetArch)"
127+
128+
cd "$(Build.SourcesDirectory)\mssql_python\pybind"
129+
130+
REM Optional: override lib path if building for ARM64 since we cannot install arm64 python on x64 host
131+
if "$(targetArch)"=="arm64" (
132+
echo Using arm64-specific Python library...
133+
set CUSTOM_PYTHON_LIB_DIR=$(Build.SourcesDirectory)\mssql_python\pybind\python_libs\arm64
134+
)
135+
136+
REM Call build.bat to build the PYD file
137+
call build.bat $(targetArch)
138+
139+
REM Calling keep_single_arch.bat to remove ODBC libs of other architectures
140+
call keep_single_arch.bat $(targetArch)
141+
142+
cd ..\..
143+
displayName: 'Build PYD for $(targetArch)'
144+
145+
# Copy the built .pyd file to staging folder for artifacts
146+
- task: CopyFiles@2
147+
inputs:
148+
SourceFolder: '$(Build.SourcesDirectory)\mssql_python\pybind\build\$(targetArch)\py$(shortPyVer)\Release'
149+
Contents: 'ddbc_bindings.cp$(shortPyVer)-*.pyd'
150+
TargetFolder: '$(Build.ArtifactStagingDirectory)\all-pyds\$(shortPyVer)\$(targetArch)'
151+
displayName: 'Place PYD file into artifacts directory'
152+
153+
# Build wheel package for the current architecture
154+
- script: |
155+
python -m pip install --upgrade pip
156+
pip install wheel
157+
set ARCHITECTURE=$(targetArch)
158+
python setup.py bdist_wheel
159+
displayName: 'Build wheel package for Python $(pythonVersion) ($(targetArch))'
160+
161+
# Copy the wheel file to the artifacts
162+
- task: CopyFiles@2
163+
inputs:
164+
SourceFolder: '$(Build.SourcesDirectory)\dist'
165+
Contents: '*.whl'
166+
TargetFolder: '$(Build.ArtifactStagingDirectory)\dist'
167+
displayName: 'Collect wheel package'
168+
169+
# Publish the collected .pyd file(s) as build artifacts
170+
- task: PublishBuildArtifacts@1
171+
condition: succeededOrFailed()
172+
inputs:
173+
PathtoPublish: '$(Build.ArtifactStagingDirectory)\all-pyds'
174+
ArtifactName: 'mssql-python-pyds'
175+
publishLocation: 'Container'
176+
displayName: 'Publish all PYDs as artifacts'
177+
178+
# Publish the collected wheel file(s) as build artifacts
179+
- task: PublishBuildArtifacts@1
180+
condition: succeededOrFailed()
181+
inputs:
182+
PathtoPublish: '$(Build.ArtifactStagingDirectory)\dist'
183+
ArtifactName: 'mssql-python-wheels-dist'
184+
publishLocation: 'Container'
185+
displayName: 'Publish all wheels as artifacts'

eng/pipelines/test-pipeline.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,5 +65,5 @@ jobs:
6565
- task: PublishCodeCoverageResults@1
6666
inputs:
6767
codeCoverageTool: 'Cobertura'
68-
summaryFileLocation: 'coverage.xml'
68+
summaryFileLocation: '$(System.DefaultWorkingDirectory)/**/coverage.xml'
6969
displayName: 'Publish code coverage results'

main.py

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,31 @@
1212

1313
cursor = conn.cursor()
1414
cursor.execute("SELECT database_id, name from sys.databases;")
15-
rows = cursor.fetchall()
15+
row = cursor.fetchmany(1)
16+
print(row)
1617

17-
for row in rows:
18-
print(f"Database ID: {row[0]}, Name: {row[1]}")
18+
cursor.execute("DROP TABLE IF EXISTS main_single_column")
19+
20+
# cursor.execute("CREATE TABLE main_single_column (float_column FLOAT)")
21+
# cursor.executemany("INSERT INTO main_single_column (float_column) VALUES (?)", [[12.34], [1.234], [0.125], [0.0125], [0.00125], [23243243232.432432432], [0.247985732852735032750973209750]])
22+
# cursor.execute("SELECT * FROM main_single_column")
23+
# row = cursor.fetchall()
24+
# print(row)
25+
# print(len(row))
26+
27+
import time
28+
cursor.execute("CREATE TABLE main_single_column (decimal_column NUMERIC(10, 4))")
29+
# time.sleep(45)
30+
31+
cursor.execute("INSERT INTO main_single_column (decimal_column) VALUES (?)", [decimal.Decimal(123.45).quantize(decimal.Decimal('0.00'))])
32+
cursor.execute("SELECT * FROM main_single_column")
33+
row = cursor.fetchone()[0]
34+
35+
print(row)
36+
print(row.val)
37+
print(row.precision)
38+
print(row.scale)
39+
print(row.sign)
1940

2041
cursor.close()
2142
conn.close()

0 commit comments

Comments
 (0)