Skip to content

Commit

Permalink
Adding extra options to deeper configure sqlalchemy
Browse files Browse the repository at this point in the history
  • Loading branch information
mistercrunch committed Apr 4, 2016
1 parent f1830c3 commit 8898444
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
"""Adding extra field to Database model
Revision ID: 867bf4f117f9
Revises: fee7b758c130
Create Date: 2016-04-03 15:23:20.280841
"""

# revision identifiers, used by Alembic.
revision = '867bf4f117f9'
down_revision = 'fee7b758c130'

from alembic import op
import sqlalchemy as sa


def upgrade():
op.add_column('dbs', sa.Column('extra', sa.Text(), nullable=True))


def downgrade():
op.drop_column('dbs', 'extra')
23 changes: 21 additions & 2 deletions caravel/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from six import string_types
import sqlparse
import requests
import textwrap

from dateutil.parser import parse
from flask import flash, request, g
Expand Down Expand Up @@ -292,12 +293,20 @@ class Database(Model, AuditMixinNullable):
sqlalchemy_uri = Column(String(1024))
password = Column(EncryptedType(String(1024), config.get('SECRET_KEY')))
cache_timeout = Column(Integer)
extra = Column(Text, default=textwrap.dedent("""\
{
"metadata_params": {},
"engine_params": {},
}
"""))

def __repr__(self):
return self.database_name

def get_sqla_engine(self):
return create_engine(self.sqlalchemy_uri_decrypted)
extra = self.get_extra()
params = extra.get('engine_params', {})
return create_engine(self.sqlalchemy_uri_decrypted, **params)

def safe_sqlalchemy_uri(self):
return self.sqlalchemy_uri
Expand Down Expand Up @@ -336,8 +345,18 @@ def grains(self):
def grains_dict(self):
return {grain.name: grain for grain in self.grains()}

def get_extra(self):
extra = {}
if self.extra:
try:
extra = json.loads(self.extra)
except Exception as e:
logging.error(e)
return extra

def get_table(self, table_name):
meta = MetaData()
extra = self.get_extra()
meta = MetaData(**extra.get('metadata_params', {}))
return Table(
table_name, meta,
autoload=True,
Expand Down
8 changes: 6 additions & 2 deletions caravel/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from sqlalchemy.types import TypeDecorator, TEXT
from markdown import markdown as md
import parsedatetime
from flask import Markup
from flask_appbuilder.security.sqla import models as ab_models


Expand Down Expand Up @@ -241,13 +242,16 @@ def json_iso_dttm_ser(obj):
return obj


def markdown(s):
def markdown(s, markup_wrap=False):
s = s or ''
return md(s, [
s = md(s, [
'markdown.extensions.tables',
'markdown.extensions.fenced_code',
'markdown.extensions.codehilite',
])
if markup_wrap:
s = Markup(s)
return s


def readfile(filepath):
Expand Down
14 changes: 12 additions & 2 deletions caravel/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,8 @@ class DatabaseView(CaravelModelView, DeleteMixin): # noqa
datamodel = SQLAInterface(models.Database)
list_columns = ['database_name', 'sql_link', 'created_by_', 'changed_on']
order_columns = utils.list_minus(list_columns, ['created_by_'])
add_columns = ['database_name', 'sqlalchemy_uri', 'cache_timeout']
add_columns = [
'database_name', 'sqlalchemy_uri', 'cache_timeout', 'extra']
search_exclude_columns = ('password',)
edit_columns = add_columns
add_template = "caravel/models/database/add.html"
Expand All @@ -127,7 +128,16 @@ class DatabaseView(CaravelModelView, DeleteMixin): # noqa
'sqlalchemy_uri': (
"Refer to the SqlAlchemy docs for more information on how "
"to structure your URI here: "
"http://docs.sqlalchemy.org/en/rel_1_0/core/engines.html")
"http://docs.sqlalchemy.org/en/rel_1_0/core/engines.html"),
'extra': utils.markdown(
"JSON string containing extra configuration elements. "
"The ``engine_params`` object gets unpacked into the "
"[sqlalchemy.create_engine]"
"(http://docs.sqlalchemy.org/en/latest/core/engines.html#"
"sqlalchemy.create_engine) call, while the ``metadata_params`` "
"gets unpacked into the [sqlalchemy.MetaData]"
"(http://docs.sqlalchemy.org/en/rel_1_0/core/metadata.html"
"#sqlalchemy.schema.MetaData) call. ", True),
}

def pre_add(self, db):
Expand Down

0 comments on commit 8898444

Please sign in to comment.