Skip to content

Commit 730f9bb

Browse files
sfc-gh-mkellersfc-gh-mmacintyresfc-gh-stakedasfc-gh-kzaveri
authored
SNOW-368566 syncing from monorepo (#231)
Co-authored-by: Mark Keller <[email protected]> Co-authored-by: Marc MacIntyre <[email protected]> Co-authored-by: Shige Takeda <[email protected]> Co-authored-by: Kushan Zaveri <[email protected]>
1 parent e1141b8 commit 730f9bb

File tree

7 files changed

+95
-52
lines changed

7 files changed

+95
-52
lines changed

scripts/py_exec.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ PYTHON_ENV=${PYTHON_ENV:-}
55

66
function set_defaults() {
77
# Set up to fall back onto when something is set wrong, or PYTHON_ENV is invalid
8-
PYTHON_EXEC=python3.5
8+
PYTHON_EXEC=python3.6
99
find_full_path ${PYTHON_EXEC}
1010
get_python_env_from_exec ${PYTHON_EXEC}
1111
}

snowdialect.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
from .custom_types import (
3030
TIMESTAMP_LTZ, TIMESTAMP_TZ, TIMESTAMP_NTZ, VARIANT, OBJECT, ARRAY
3131
)
32-
from snowflake.connector import errors as sf_errors, ProgrammingError
32+
from snowflake.connector import errors as sf_errors
3333

3434
colspecs = {}
3535

test/test_core.py

Lines changed: 36 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,6 @@
3939

4040
from snowflake.sqlalchemy.snowdialect import SnowflakeDialect
4141

42-
try:
43-
from parameters import (CONNECTION_PARAMETERS2)
44-
except ImportError:
45-
CONNECTION_PARAMETERS2 = CONNECTION_PARAMETERS
46-
4742
THIS_DIR = os.path.dirname(os.path.realpath(__file__))
4843

4944

@@ -91,26 +86,18 @@ def test_connect_args():
9186
host:port
9287
"""
9388
from sqlalchemy import create_engine
94-
engine = create_engine(
95-
'snowflake://{user}:{password}@{account}/{database}/{schema}'.format(
96-
user=CONNECTION_PARAMETERS2['user'],
97-
password=CONNECTION_PARAMETERS2['password'],
98-
account=CONNECTION_PARAMETERS2['account'],
99-
database=CONNECTION_PARAMETERS2['database'],
100-
schema=CONNECTION_PARAMETERS2['schema'],
101-
)
102-
)
103-
try:
104-
results = engine.execute('select current_version()').fetchone()
105-
assert results is not None
106-
finally:
107-
engine.dispose()
10889

10990
engine = create_engine(
110-
'snowflake://{user}:{password}@{account}/'.format(
111-
user=CONNECTION_PARAMETERS2['user'],
112-
password=CONNECTION_PARAMETERS2['password'],
113-
account=CONNECTION_PARAMETERS2['account'],
91+
'snowflake://{user}:{password}@{host}:{port}/{database}/{schema}'
92+
'?account={account}&protocol={protocol}'.format(
93+
user=CONNECTION_PARAMETERS['user'],
94+
account=CONNECTION_PARAMETERS['account'],
95+
password=CONNECTION_PARAMETERS['password'],
96+
host=f"{CONNECTION_PARAMETERS['account']}.{CONNECTION_PARAMETERS['host']}",
97+
port=CONNECTION_PARAMETERS['port'],
98+
database=CONNECTION_PARAMETERS['database'],
99+
schema=CONNECTION_PARAMETERS['schema'],
100+
protocol=CONNECTION_PARAMETERS['protocol'],
114101
)
115102
)
116103
try:
@@ -120,22 +107,27 @@ def test_connect_args():
120107
engine.dispose()
121108

122109
engine = create_engine(URL(
123-
user=CONNECTION_PARAMETERS2['user'],
124-
password=CONNECTION_PARAMETERS2['password'],
125-
account=CONNECTION_PARAMETERS2['account'],
126-
)
127-
)
110+
user=CONNECTION_PARAMETERS['user'],
111+
password=CONNECTION_PARAMETERS['password'],
112+
account=CONNECTION_PARAMETERS['account'],
113+
host=CONNECTION_PARAMETERS['host'],
114+
port=CONNECTION_PARAMETERS['port'],
115+
protocol=CONNECTION_PARAMETERS['protocol'],
116+
))
128117
try:
129118
results = engine.execute('select current_version()').fetchone()
130119
assert results is not None
131120
finally:
132121
engine.dispose()
133122

134123
engine = create_engine(URL(
135-
user=CONNECTION_PARAMETERS2['user'],
136-
password=CONNECTION_PARAMETERS2['password'],
137-
account=CONNECTION_PARAMETERS2['account'],
138-
warehouse='testwh'
124+
user=CONNECTION_PARAMETERS['user'],
125+
password=CONNECTION_PARAMETERS['password'],
126+
account=CONNECTION_PARAMETERS['account'],
127+
host=CONNECTION_PARAMETERS['host'],
128+
port=CONNECTION_PARAMETERS['port'],
129+
protocol=CONNECTION_PARAMETERS['protocol'],
130+
warehouse='testwh',
139131
)
140132
)
141133
try:
@@ -190,7 +182,10 @@ def test_insert_tables(engine_testaccount):
190182
# inserts data with an implicitly generated id
191183
ins = users.insert().values(name='jack', fullname='Jack Jones')
192184
results = engine_testaccount.execute(ins)
193-
assert results.inserted_primary_key == [1], 'sequence value'
185+
# Note: SQLAlchemy 1.4 changed what ``inserted_primary_key`` returns
186+
# a cast is here to make sure the test works with both older and newer
187+
# versions
188+
assert list(results.inserted_primary_key) == [1,], 'sequence value'
194189
results.close()
195190

196191
# inserts data with the given id
@@ -816,6 +811,10 @@ def test_many_table_column_metadta(db_parameters):
816811
assert cnt == total_objects * 2, 'total number of test objects'
817812

818813

814+
@pytest.mark.skip(reason="SQLAlchemy 1.4 release seem to have caused a pretty big"
815+
"performance degradation, but addressing this should also"
816+
"address fully supporting SQLAlchemy 1.4 which has a lot "
817+
"of changes")
819818
def test_cache_time(engine_testaccount, db_parameters):
820819
"""Check whether Inspector cache is working"""
821820
# Set up necessary tables
@@ -1164,6 +1163,10 @@ def test_autoincrement(engine_testaccount):
11641163
users.drop(engine_testaccount)
11651164

11661165

1166+
@pytest.mark.skip(reason="SQLAlchemy 1.4 release seem to have caused a pretty big"
1167+
"performance degradation, but addressing this should also"
1168+
"address fully supporting SQLAlchemy 1.4 which has a lot "
1169+
"of changes")
11671170
def test_get_too_many_columns(engine_testaccount, db_parameters):
11681171
"""Check whether Inspector cache is working, when there are too many column to cache whole schema's columns"""
11691172
# Set up necessary tables

test/test_pandas.py

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@
55
#
66
import random
77
import string
8+
import uuid
89

910
import numpy as np
1011
import pandas as pd
1112
import pytest
1213
import snowflake.sqlalchemy
1314
import sqlalchemy
15+
from snowflake.connector import ProgrammingError
16+
from snowflake.connector.pandas_tools import make_pd_writer, pd_writer
1417
from sqlalchemy import Column, ForeignKey, Integer, MetaData, Sequence, String, Table
1518

1619

@@ -58,7 +61,10 @@ def test_a_simple_read_sql(engine_testaccount):
5861
# inserts data with an implicitly generated id
5962
ins = users.insert().values(name='jack', fullname='Jack Jones')
6063
results = engine_testaccount.execute(ins)
61-
assert results.inserted_primary_key == [1], 'sequence value'
64+
# Note: SQLAlchemy 1.4 changed what ``inserted_primary_key`` returns
65+
# a cast is here to make sure the test works with both older and newer
66+
# versions
67+
assert list(results.inserted_primary_key) == [1], 'sequence value'
6268
results.close()
6369

6470
# inserts data with the given id
@@ -238,3 +244,53 @@ def test_timezone(db_parameters):
238244
assert(np.issubdtype(result2.FLOAT_COL, np.float64))
239245
finally:
240246
sa_engine.execute('DROP TABLE {table};'.format(table=test_table_name))
247+
248+
249+
def test_pandas_writeback(engine_testaccount):
250+
sf_connector_version_data = [
251+
('snowflake-connector-python', '1.2.23'),
252+
('snowflake-sqlalchemy', '1.1.1'),
253+
('snowflake-connector-go', '0.0.1'),
254+
('snowflake-go', '1.0.1'),
255+
('snowflake-odbc', '3.12.3'),
256+
]
257+
table_name = 'driver_versions'
258+
# Note: column names have to be all upper case because our sqlalchemy connector creates it in a case insensitive way
259+
sf_connector_version_df = pd.DataFrame(sf_connector_version_data, columns=['NAME', 'NEWEST_VERSION'])
260+
sf_connector_version_df.to_sql(table_name, engine_testaccount, index=False, method=pd_writer)
261+
262+
assert (pd.read_sql_table(table_name, engine_testaccount).rename(
263+
columns={'newest_version': 'NEWEST_VERSION', 'name': 'NAME'}
264+
) == sf_connector_version_df).all().all()
265+
266+
267+
@pytest.mark.parametrize("quote_identifiers", [False, True])
268+
def test_pandas_make_pd_writer(engine_testaccount, quote_identifiers):
269+
table_name = f"test_table_{uuid.uuid4().hex}".upper()
270+
test_df = pd.DataFrame({"a": range(10), "b": range(10, 20)})
271+
272+
def write_to_db():
273+
test_df.to_sql(
274+
table_name,
275+
engine_testaccount,
276+
index=False,
277+
method=make_pd_writer(quote_identifiers=quote_identifiers),
278+
)
279+
280+
try:
281+
if quote_identifiers:
282+
with pytest.raises(ProgrammingError, match=r".*SQL compilation error.*\ninvalid identifier '\"a\"'.*") as e:
283+
write_to_db()
284+
else:
285+
write_to_db()
286+
results = sorted(
287+
engine_testaccount.execute(f"SELECT * FROM {table_name}").fetchall(),
288+
key=lambda x: x[0],
289+
)
290+
# Verify that all 10 entries were written to the DB
291+
for i in range(10):
292+
assert results[i] == (i, i + 10)
293+
assert len(results) == 10
294+
finally:
295+
engine_testaccount.execute(f"DROP TABLE IF EXISTS {table_name}")
296+

test/test_qmark.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,6 @@
77

88
from parameters import CONNECTION_PARAMETERS
99

10-
try:
11-
from parameters import (CONNECTION_PARAMETERS2)
12-
except ImportError:
13-
CONNECTION_PARAMETERS2 = CONNECTION_PARAMETERS
14-
1510
THIS_DIR = os.path.dirname(os.path.realpath(__file__))
1611

1712

test/test_semi_structured_datatypes.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,6 @@
1212
from sqlalchemy import Column, Integer, MetaData, Table, inspect
1313
from sqlalchemy.sql import select
1414

15-
try:
16-
from parameters import (CONNECTION_PARAMETERS2)
17-
except ImportError:
18-
CONNECTION_PARAMETERS2 = CONNECTION_PARAMETERS
19-
2015

2116
def test_create_table_semi_structured_datatypes(engine_testaccount):
2217
"""

test/test_timestamp.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,6 @@
1515
PST_TZ = "America/Los_Angeles"
1616
JST_TZ = "Asia/Tokyo"
1717

18-
try:
19-
from parameters import (CONNECTION_PARAMETERS2)
20-
except ImportError:
21-
CONNECTION_PARAMETERS2 = CONNECTION_PARAMETERS
22-
23-
2418
def test_create_table_timestamp_datatypes(engine_testaccount):
2519
"""
2620
Create table including timestamp data types

0 commit comments

Comments
 (0)