-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rewrite materializations with statement
block
#466
Changes from all commits
6da8662
7a632c6
a41e184
6cc5ad3
f6c3c19
3770897
8be612b
a0c67bf
e2b2d6b
9d21d97
b671307
d19c271
61ace92
b618727
7258665
f1973cb
2746df7
da4ea7a
01f6457
7078fb6
e22c218
7cbc924
3e64775
ca783ba
1f062f3
7a3de02
d62486e
ddfdbc0
f6cdf63
75896e5
17661a6
3f60e0a
403bbdd
876417d
10b3dbb
a9d7ee7
a99fbfe
e1bcf95
ae848c3
8a1698b
ef06431
fc54094
4f207d4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,12 @@ | ||
import copy | ||
import itertools | ||
import multiprocessing | ||
import re | ||
import time | ||
import yaml | ||
|
||
from contextlib import contextmanager | ||
|
||
import dbt.exceptions | ||
import dbt.flags | ||
import dbt.materializers | ||
|
||
from dbt.contracts.connection import validate_connection | ||
from dbt.logger import GLOBAL_LOGGER as logger | ||
|
@@ -24,9 +22,22 @@ class DefaultAdapter(object): | |
|
||
requires = {} | ||
|
||
@classmethod | ||
def get_materializer(cls, model, existing): | ||
return dbt.materializers.get_materializer(cls, model, existing) | ||
context_functions = [ | ||
"already_exists", | ||
"get_columns_in_table", | ||
"get_missing_columns", | ||
"query_for_existing", | ||
"rename", | ||
"drop", | ||
"truncate", | ||
"add_query", | ||
"expand_target_column_types", | ||
] | ||
|
||
raw_functions = [ | ||
"get_status", | ||
"get_result_from_cursor" | ||
] | ||
|
||
### | ||
# ADAPTER-SPECIFIC FUNCTIONS -- each of these must be overridden in | ||
|
@@ -49,16 +60,6 @@ def date_function(cls): | |
raise dbt.exceptions.NotImplementedException( | ||
'`date_function` is not implemented for this adapter!') | ||
|
||
@classmethod | ||
def dist_qualifier(cls): | ||
raise dbt.exceptions.NotImplementedException( | ||
'`dist_qualifier` is not implemented for this adapter!') | ||
|
||
@classmethod | ||
def sort_qualifier(cls): | ||
raise dbt.exceptions.NotImplementedException( | ||
'`sort_qualifier` is not implemented for this adapter!') | ||
|
||
@classmethod | ||
def get_status(cls, cursor): | ||
raise dbt.exceptions.NotImplementedException( | ||
|
@@ -88,6 +89,18 @@ def cancel_connection(cls, project, connection): | |
### | ||
# FUNCTIONS THAT SHOULD BE ABSTRACT | ||
### | ||
@classmethod | ||
def get_result_from_cursor(cls, cursor): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nitpicky, but this probably doesn't belong under |
||
data = [] | ||
|
||
if cursor.description is not None: | ||
column_names = [col[0] for col in cursor.description] | ||
raw_results = cursor.fetchall() | ||
data = [dict(zip(column_names, row)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this could so readily be a |
||
for row in raw_results] | ||
|
||
return data | ||
|
||
@classmethod | ||
def drop(cls, profile, relation, relation_type, model_name=None): | ||
if relation_type == 'view': | ||
|
@@ -144,35 +157,6 @@ def rename(cls, profile, from_name, to_name, model_name=None): | |
def is_cancelable(cls): | ||
return True | ||
|
||
@classmethod | ||
def execute_model(cls, profile, model): | ||
parts = re.split(r'-- (DBT_OPERATION .*)', model.get('wrapped_sql')) | ||
|
||
for i, part in enumerate(parts): | ||
matches = re.match(r'^DBT_OPERATION ({.*})$', part) | ||
if matches is not None: | ||
instruction_string = matches.groups()[0] | ||
instruction = yaml.safe_load(instruction_string) | ||
function = instruction['function'] | ||
kwargs = instruction['args'] | ||
|
||
def call_expand_target_column_types(kwargs): | ||
kwargs.update({'profile': profile, | ||
'model_name': model.get('name')}) | ||
return cls.expand_target_column_types(**kwargs) | ||
|
||
func_map = { | ||
'expand_column_types_if_needed': | ||
call_expand_target_column_types | ||
} | ||
|
||
func_map[function](kwargs) | ||
else: | ||
connection, cursor = cls.add_query( | ||
profile, part, model.get('name')) | ||
|
||
return cls.get_status(cursor) | ||
|
||
@classmethod | ||
def get_missing_columns(cls, profile, | ||
from_schema, from_table, | ||
|
@@ -259,27 +243,6 @@ def get_drop_schema_sql(cls, schema): | |
return ('drop schema if exists "{schema} cascade"' | ||
.format(schema=schema)) | ||
|
||
@classmethod | ||
def get_create_table_sql(cls, schema, table, columns, sort, dist): | ||
fields = ['"{field}" {data_type}'.format( | ||
field=column.name, data_type=column.data_type | ||
) for column in columns] | ||
fields_csv = ",\n ".join(fields) | ||
dist = cls.dist_qualifier(dist) | ||
sort = cls.sort_qualifier('compound', sort) | ||
sql = """ | ||
create table if not exists "{schema}"."{table}" ( | ||
{fields} | ||
) | ||
{dist} {sort} | ||
""".format( | ||
schema=schema, | ||
table=table, | ||
fields=fields_csv, | ||
sort=sort, | ||
dist=dist).strip() | ||
return sql | ||
|
||
### | ||
# ODBC FUNCTIONS -- these should not need to change for every adapter, | ||
# although some adapters may override them | ||
|
@@ -595,13 +558,6 @@ def drop_schema(cls, profile, schema, model_name=None): | |
sql = cls.get_drop_schema_sql(schema) | ||
return cls.add_query(profile, sql, model_name) | ||
|
||
@classmethod | ||
def create_table(cls, profile, schema, table, columns, sort, dist, | ||
model_name=None): | ||
logger.debug('Creating table "%s"."%s".', schema, table) | ||
sql = cls.get_create_table_sql(schema, table, columns, sort, dist) | ||
return cls.add_query(profile, sql, model_name) | ||
|
||
@classmethod | ||
def table_exists(cls, profile, schema, table, model_name=None): | ||
tables = cls.query_for_existing(profile, schema, model_name) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what's the difference between a raw func and a context func?