Skip to content

Commit 136212a

Browse files
sfc-gh-stakedaankit-bhatnagar167
authored andcommitted
SNOW-118293: Fixed special character handling in snowflake-sqlalchemy from URL string
1 parent 9c1c011 commit 136212a

File tree

2 files changed

+38
-4
lines changed

2 files changed

+38
-4
lines changed

snowdialect.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
#
66

77
import operator
8+
from six.moves.urllib_parse import unquote_plus
9+
810
import sqlalchemy.types as sqltypes
911
from six import iteritems
1012
from sqlalchemy import util as sa_util
@@ -141,7 +143,7 @@ def dbapi(cls):
141143
def create_connect_args(self, url):
142144
opts = url.translate_connect_args(username='user')
143145
if 'database' in opts:
144-
name_spaces = opts['database'].split('/')
146+
name_spaces = [unquote_plus(e) for e in opts['database'].split('/')]
145147
if len(name_spaces) == 1:
146148
pass
147149
elif len(name_spaces) == 2:

test/test_core.py

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,10 @@
1313
from parameters import CONNECTION_PARAMETERS
1414
from sqlalchemy import Table, Column, Integer, Numeric, String, MetaData, Sequence, ForeignKey, LargeBinary, REAL, \
1515
Boolean, DateTime
16-
from sqlalchemy import inspect
17-
from sqlalchemy import text
18-
from sqlalchemy import dialects
16+
from sqlalchemy import create_engine, dialects, inspect, text
1917
from sqlalchemy.sql import and_, or_, not_
2018
from sqlalchemy.sql import select
19+
from snowflake.connector import connect
2120

2221
from snowflake.sqlalchemy import (
2322
URL,
@@ -1037,3 +1036,36 @@ def test_comment_sqlalchemy(db_parameters, engine_testaccount, on_travis):
10371036
con2.close()
10381037
engine2.dispose()
10391038

1039+
1040+
1041+
@pytest.mark.skipif(
1042+
os.getenv('TRAVIS') == 'true',
1043+
reason="Travis cannot create Schemas and Databases"
1044+
)
1045+
def test_special_schema_character(db_parameters):
1046+
"""Make sure we decode special characters correctly"""
1047+
# Constants
1048+
database = "a/b/c" # "'/'.join([choice(ascii_lowercase) for _ in range(3)])
1049+
schema = "d/e/f" # '/'.join([choice(ascii_lowercase) for _ in range(3)])
1050+
# Setup
1051+
options = dict(**db_parameters)
1052+
conn = connect(**options)
1053+
conn.cursor().execute("CREATE OR REPLACE DATABASE \"{0}\"".format(database))
1054+
conn.cursor().execute("CREATE OR REPLACE SCHEMA \"{0}\"".format(schema))
1055+
conn.close()
1056+
# Test
1057+
options.update({'database': '"' + database + '"',
1058+
'schema': '"' + schema + '"'})
1059+
sf_conn = connect(**options)
1060+
sf_connection = [res for res in sf_conn.cursor().execute("select current_database(), "
1061+
"current_schema();")]
1062+
sa_conn = create_engine(URL(**options)).connect()
1063+
sa_connection = [res for res in sa_conn.execute("select current_database(), "
1064+
"current_schema();")]
1065+
sa_conn.close()
1066+
sf_conn.close()
1067+
# Teardown
1068+
conn = connect(**options)
1069+
conn.cursor().execute("DROP DATABASE IF EXISTS \"{0}\"".format(database))
1070+
conn.close()
1071+
assert [(database, schema)] == sf_connection == sa_connection

0 commit comments

Comments
 (0)