Skip to content

Commit d9423ac

Browse files
committed
Added UnloadFromSelect and associated tests. Also added build/ to .gitignore
Signed-off-by: Jason Myers <[email protected]>
1 parent 1986edc commit d9423ac

File tree

3 files changed

+39
-0
lines changed

3 files changed

+39
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@
33
.DS_Store
44
dist
55
*.egg-info
6+
build

redshift_sqlalchemy/dialect.py

+20
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
from sqlalchemy.engine import reflection
33
from sqlalchemy import util, exc
44
from sqlalchemy.types import VARCHAR, NullType
5+
from sqlalchemy.ext.compiler import compiles
6+
from sqlalchemy.sql.expression import Executable, ClauseElement
7+
58

69
class RedshiftDialect(PGDialect_psycopg2):
710
@reflection.cache
@@ -51,3 +54,20 @@ def _get_column_info(self, name, format_type, default,
5154
if isinstance(column_info['type'], VARCHAR) and column_info['type'].length is None:
5255
column_info['type'] = NullType()
5356
return column_info
57+
58+
59+
class UnloadFromSelect(Executable, ClauseElement):
60+
def __init__(self, select, bucket, access_key, secret_key):
61+
self.select = select
62+
self.bucket = bucket
63+
self.access_key = access_key
64+
self.secret_key = secret_key
65+
66+
@compiles(UnloadFromSelect)
67+
def visit_unload_from_select(element, compiler, **kw):
68+
return "unload ('%(query)s') to '%(bucket)s' credentials 'aws_access_key_id=%(access_key)s;aws_secret_access_key=%(secret_key)s'" % {
69+
'query': element.select,
70+
'bucket': element.bucket,
71+
'access_key': element.access_key,
72+
'secret_key': element.secret_key,
73+
}

tests/test_unload_from_select.py

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from unittest import TestCase
2+
from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey, create_engine
3+
from sqlalchemy.sql import select, func
4+
from sqlalchemy.types import NullType, VARCHAR
5+
from redshift_sqlalchemy.dialect import RedshiftDialect, UnloadFromSelect, visit_unload_from_select
6+
7+
8+
class TestUnloadFromSelect(TestCase):
9+
def setUp(self):
10+
self.metadata = MetaData()
11+
self.t1 = Table('t1', self.metadata, Column('id', Integer, primary_key=True), Column('name', String))
12+
self.engine = create_engine('sqlite:///:memory:', echo=True)
13+
self.metadata.create_all(self.engine)
14+
15+
def test_basic_unload_case(self):
16+
expected_result = "unload ('SELECT count(t1.id) AS count_1 \nFROM t1') to 'cookies' credentials 'aws_access_key_id=cookies;aws_secret_access_key=cookies'"
17+
insert = UnloadFromSelect(select([func.count(self.t1.c.id)]), 'cookies', 'cookies', 'cookies')
18+
self.assertEqual(expected_result, str(insert))

0 commit comments

Comments
 (0)