Skip to content

Commit 7909397

Browse files
committed
Try to test in github
1 parent dfdeee0 commit 7909397

3 files changed

Lines changed: 113 additions & 61 deletions

File tree

.github/workflows/codeql-analysis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#
1212
name: "CodeQL"
1313

14-
on: [push, pull_request]
14+
on: [workflow_dispatch]
1515

1616
jobs:
1717
analyze:

.github/workflows/ubuntu_build.yml

Lines changed: 59 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name: Ubuntu build
22

33
# include "workflow_dispatch" so this workflow can be run manually from the Actions portal
4-
on: [push, pull_request, workflow_dispatch]
4+
on: [pull_request, workflow_dispatch]
55

66
jobs:
77
run_tests:
@@ -12,7 +12,7 @@ jobs:
1212
strategy:
1313
fail-fast: false
1414
matrix:
15-
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
15+
python-version: ["3.13"]
1616

1717
services:
1818

@@ -40,26 +40,26 @@ jobs:
4040
ACCEPT_EULA: Y
4141
SA_PASSWORD: StrongPassword2025
4242

43-
postgres:
44-
image: postgres:13
45-
env:
46-
POSTGRES_DB: postgres_db
47-
POSTGRES_USER: postgres_user
48-
POSTGRES_PASSWORD: postgres_pwd
49-
ports:
50-
- 5432:5432
51-
# needed because the postgres container does not provide a healthcheck
52-
options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
43+
# postgres:
44+
# image: postgres:13
45+
# env:
46+
# POSTGRES_DB: postgres_db
47+
# POSTGRES_USER: postgres_user
48+
# POSTGRES_PASSWORD: postgres_pwd
49+
# ports:
50+
# - 5432:5432
51+
# # needed because the postgres container does not provide a healthcheck
52+
# options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
5353

5454
steps:
5555

5656
# to ensure the drivers are installed correctly with apt-get
5757
- name: apt-get update
5858
run: sudo apt-get update
5959

60-
- name: Start MySQL service
61-
run: |
62-
sudo systemctl start mysql.service
60+
# - name: Start MySQL service
61+
# run: |
62+
# sudo systemctl start mysql.service
6363

6464
- name: Check initial setup
6565
run: |
@@ -144,28 +144,28 @@ jobs:
144144
echo "*** SQL Server 2025"
145145
docker exec -i "${{ job.services.mssql2025.id }}" /opt/mssql-tools18/bin/sqlcmd -S localhost -U SA -P 'StrongPassword2025' -C -Q "SELECT @@VERSION" || sleep 5
146146
docker exec -i "${{ job.services.mssql2025.id }}" /opt/mssql-tools18/bin/sqlcmd -S localhost -U SA -P 'StrongPassword2025' -C -Q "CREATE DATABASE test"
147-
148-
- name: Create test database in PostgreSQL
149-
run: |
150-
echo "*** get version"
151-
psql -c "SELECT version()"
152-
echo "*** create database"
153-
psql -c "CREATE DATABASE test WITH encoding='UTF8' LC_COLLATE='en_US.utf8' LC_CTYPE='en_US.utf8'"
154-
echo "*** list databases"
155-
psql -l
156-
env:
157-
PGHOST: localhost
158-
PGPORT: 5432
159-
PGDATABASE: postgres_db
160-
PGUSER: postgres_user
161-
PGPASSWORD: postgres_pwd
162-
163-
- name: Create test database in MySQL
164-
run: |
165-
echo "*** get status"
166-
mysql --user=root --password=root --execute "STATUS"
167-
echo "*** create database"
168-
mysql --user=root --password=root --execute "CREATE DATABASE test"
147+
#
148+
# - name: Create test database in PostgreSQL
149+
# run: |
150+
# echo "*** get version"
151+
# psql -c "SELECT version()"
152+
# echo "*** create database"
153+
# psql -c "CREATE DATABASE test WITH encoding='UTF8' LC_COLLATE='en_US.utf8' LC_CTYPE='en_US.utf8'"
154+
# echo "*** list databases"
155+
# psql -l
156+
# env:
157+
# PGHOST: localhost
158+
# PGPORT: 5432
159+
# PGDATABASE: postgres_db
160+
# PGUSER: postgres_user
161+
# PGPASSWORD: postgres_pwd
162+
#
163+
# - name: Create test database in MySQL
164+
# run: |
165+
# echo "*** get status"
166+
# mysql --user=root --password=root --execute "STATUS"
167+
# echo "*** create database"
168+
# mysql --user=root --password=root --execute "CREATE DATABASE test"
169169

170170
- uses: actions/checkout@v4.3.0
171171

@@ -197,43 +197,43 @@ jobs:
197197
python -c "import pyodbc; print(pyodbc.version)"
198198
echo "*** pyodbc drivers"
199199
python -c "import pyodbc; print('\n'.join(sorted(pyodbc.drivers())))"
200-
201-
- name: Run PostgreSQL tests
202-
env:
203-
PYODBC_POSTGRESQL: "DRIVER={PostgreSQL Unicode};SERVER=localhost;PORT=5432;UID=postgres_user;PWD=postgres_pwd;DATABASE=test"
204-
run: |
205-
cd "$GITHUB_WORKSPACE"
206-
python -m pytest "./tests/postgresql_test.py"
207-
208-
- name: Run MySQL tests
209-
env:
210-
PYODBC_MYSQL: "DRIVER={MySQL ODBC 8.0 ANSI Driver};SERVER=localhost;UID=root;PWD=root;DATABASE=test;CHARSET=utf8mb4"
211-
run: |
212-
cd "$GITHUB_WORKSPACE"
213-
python -m pytest "./tests/mysql_test.py"
200+
#
201+
# - name: Run PostgreSQL tests
202+
# env:
203+
# PYODBC_POSTGRESQL: "DRIVER={PostgreSQL Unicode};SERVER=localhost;PORT=5432;UID=postgres_user;PWD=postgres_pwd;DATABASE=test"
204+
# run: |
205+
# cd "$GITHUB_WORKSPACE"
206+
# python -m pytest "./tests/postgresql_test.py"
207+
#
208+
# - name: Run MySQL tests
209+
# env:
210+
# PYODBC_MYSQL: "DRIVER={MySQL ODBC 8.0 ANSI Driver};SERVER=localhost;UID=root;PWD=root;DATABASE=test;CHARSET=utf8mb4"
211+
# run: |
212+
# cd "$GITHUB_WORKSPACE"
213+
# python -m pytest "./tests/mysql_test.py"
214214

215215
- name: Run SQL Server 2019 tests
216216
env:
217217
PYODBC_SQLSERVER: "DRIVER={ODBC Driver 18 for SQL Server};SERVER=localhost,1402;UID=sa;PWD=StrongPassword2019;DATABASE=test;Encrypt=Optional"
218218
run: |
219219
cd "$GITHUB_WORKSPACE"
220-
python -m pytest "./tests/sqlserver_test.py"
220+
python -m pytest -s "./tests/sqlserver_test.py"
221221
222222
- name: Run SQL Server 2022 tests
223223
env:
224224
PYODBC_SQLSERVER: "DRIVER={ODBC Driver 18 for SQL Server};SERVER=localhost,1403;UID=sa;PWD=StrongPassword2022;DATABASE=test;Encrypt=Optional"
225225
run: |
226226
cd "$GITHUB_WORKSPACE"
227-
python -m pytest "./tests/sqlserver_test.py"
227+
python -m pytest -s "./tests/sqlserver_test.py"
228228
229229
- name: Run SQL Server 2025 tests
230230
env:
231231
PYODBC_SQLSERVER: "DRIVER={ODBC Driver 18 for SQL Server};SERVER=localhost,1404;UID=sa;PWD=StrongPassword2025;DATABASE=test;Encrypt=Optional"
232232
run: |
233233
cd "$GITHUB_WORKSPACE"
234-
python -m pytest "./tests/sqlserver_test.py"
235-
236-
- name: Run SQLite tests
237-
run: |
238-
cd "$GITHUB_WORKSPACE"
239-
python -m pytest "./tests/sqlite_test.py"
234+
python -m pytest -s "./tests/sqlserver_test.py"
235+
#
236+
# - name: Run SQLite tests
237+
# run: |
238+
# cd "$GITHUB_WORKSPACE"
239+
# python -m pytest "./tests/sqlite_test.py"

tests/sqlserver_test.py

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from collections.abc import Iterator
88
from decimal import Decimal
99
from datetime import date, time, datetime
10+
from time import time as _time
1011
from functools import lru_cache
1112

1213
import pyodbc
@@ -62,7 +63,9 @@ def _get_sqlserver_year():
6263

6364
@pytest.fixture
6465
def cursor() -> Iterator[pyodbc.Cursor]:
65-
cnxn = connect()
66+
SQL_COPT_SS_BCP = 1219
67+
SQL_BCP_ON = 1
68+
cnxn = connect(attrs_before={SQL_COPT_SS_BCP: SQL_BCP_ON})
6669
cur = cnxn.cursor()
6770

6871
cur.execute("drop table if exists t1")
@@ -1469,6 +1472,55 @@ def test_emoticons_as_literal(cursor: pyodbc.Cursor):
14691472
assert result == v
14701473

14711474

1475+
def test_performance(cursor: pyodbc.Cursor):
1476+
# benchmark_column_bind_vs_fastexecmany.py
1477+
# Setup: drop/create test table
1478+
cursor.execute("DROP TABLE IF EXISTS test_perf")
1479+
cursor.execute("""
1480+
CREATE TABLE test_perf
1481+
(
1482+
id INT,
1483+
value FLOAT,
1484+
description VARCHAR(100),
1485+
created_at DATETIME
1486+
)
1487+
""")
1488+
1489+
# Generate data
1490+
rowcount = 5000000
1491+
data = [
1492+
(i, float(i) * 1.1, f"row {i}", datetime(2020, 1, (i % 28) + 1, 12, 0, 0))
1493+
for i in range(rowcount)
1494+
]
1495+
1496+
# Method 1: fast_executemany=False
1497+
cursor.fast_executemany = False
1498+
start = _time()
1499+
cursor.executemany("INSERT INTO test_perf VALUES (?, ?, ?, ?)", data)
1500+
end = _time()
1501+
print(f"executemany: {end - start:.3f} seconds")
1502+
1503+
# Method 2: fast_executemany
1504+
cursor.fast_executemany = True
1505+
start = _time()
1506+
cursor.executemany("INSERT INTO test_perf VALUES (?, ?, ?, ?)", data)
1507+
end = _time()
1508+
print(f"fast_executemany: {end - start:.3f} seconds")
1509+
1510+
# # Method 3: bcp
1511+
cursor.fast_executemany = True
1512+
cursor.use_bcp_fast = True
1513+
cursor.bcp_batch_rows = 20000
1514+
start = _time()
1515+
cursor.executemany("INSERT INTO test_perf VALUES (?, ?, ?, ?)", data)
1516+
end = _time()
1517+
print(f"BCP Insert: {end - start:.3f} seconds")
1518+
1519+
# Verify inserted rows count
1520+
cursor.execute("SELECT COUNT(*) FROM test_perf")
1521+
print("Total rows inserted:", cursor.fetchone()[0])
1522+
1523+
14721524
def _test_tvp(cursor: pyodbc.Cursor, diff_schema):
14731525
# Test table value parameters (TVP). I like the explanation here:
14741526
#

0 commit comments

Comments
 (0)