diff --git a/contrib/connectors/pandas/models.py b/contrib/connectors/pandas/models.py index 54c194641f0c7..d87867e7f33f2 100644 --- a/contrib/connectors/pandas/models.py +++ b/contrib/connectors/pandas/models.py @@ -127,8 +127,10 @@ class PandasDatasource(Model, BaseDatasource): """A datasource based on a Pandas DataFrame""" FORMATS = [ - ('csv', 'CSV'), - ('html', 'HTML') + ('csv', 'csv'), + ('html', 'html'), + ('json', 'json'), + ('excel', 'Microsoft Excel'), ] # See http://pandas.pydata.org/pandas-docs/stable/timeseries.html#offset-aliases # NOQA @@ -159,7 +161,7 @@ class PandasDatasource(Model, BaseDatasource): name = Column(String(100), nullable=False) source_url = Column(String(1000), nullable=False) - format = Column(String(20), nullable=False) + format = Column(ChoiceType(FORMATS), nullable=False) additional_parameters = Column(JSONType) user_id = Column(Integer, ForeignKey('ab_user.id')) @@ -260,12 +262,11 @@ def data(self): d['granularity_sqla'] = utils.choicify(self.dttm_cols) d['time_grain_sqla'] = [(g, g) for g in self.GRAINS.keys()] logging.info(d) - print(d) return d @property def pandas_read_method(self): - return getattr(pd, 'read_{obj.format}'.format(obj=self)) + return getattr(pd, 'read_{obj.format.code}'.format(obj=self)) @property def pandas_read_parameters(self): diff --git a/contrib/connectors/pandas/views.py b/contrib/connectors/pandas/views.py index c02216b74b2f0..3937e4f05fb2e 100644 --- a/contrib/connectors/pandas/views.py +++ b/contrib/connectors/pandas/views.py @@ -10,6 +10,7 @@ from flask_babel import lazy_gettext as _ from flask_babel import gettext as __ +from wtforms import SelectField from superset import appbuilder, db, utils, security, sm from superset.utils import has_access @@ -22,6 +23,17 @@ from .models import PandasDatasource, PandasColumn, PandasMetric +class ChoiceTypeSelectField(SelectField): + """A SelectField based on a ChoiceType model field.""" + + def process_data(self, value): + """Use the code rather than the str() representation as data""" + try: + self.data = value.code + except AttributeError: + super(ChoiceTypeSelectField, self).process_data(value) + + class PandasColumnInlineView(CompactCRUDMixin, SupersetModelView): # noqa datamodel = SQLAInterface(PandasColumn) @@ -145,12 +157,20 @@ class PandasDatasourceModelView(DatasourceModelView, DeleteMixin): # noqa order_columns = [ 'link', 'changed_on_'] add_columns = ['name', 'source_url', 'format'] + add_form_extra_fields = { + 'format': ChoiceTypeSelectField(_('Format'), + choices=PandasDatasource.FORMATS) + } edit_columns = [ 'name', 'source_url', 'format', 'filter_select_enabled', 'slices', 'fetch_values_predicate', 'description', 'owner', 'main_dttm_col', 'default_endpoint', 'offset', 'cache_timeout'] + edit_form_extra_fields = { + 'format': ChoiceTypeSelectField(_('Format'), + choices=PandasDatasource.FORMATS) + } show_columns = edit_columns + ['perm'] related_views = [PandasColumnInlineView, PandasMetricInlineView] base_order = ('changed_on', 'desc') diff --git a/dev-reqs.txt b/dev-reqs.txt index 0a2d8b835366b..0705bd2da4a32 100644 --- a/dev-reqs.txt +++ b/dev-reqs.txt @@ -1,9 +1,7 @@ -beautifulsoup4==4.6.0 codeclimate-test-reporter coveralls flake8 flask_cors -lxml==3.8.0 mock mysqlclient nose diff --git a/setup.py b/setup.py index 53c5dc497128a..1988c10a730f7 100644 --- a/setup.py +++ b/setup.py @@ -42,6 +42,7 @@ def get_git_sha(): zip_safe=False, scripts=['superset/bin/superset'], install_requires=[ + 'beautifulsoup4==4.6.0', 'boto3==1.4.4', 'celery==3.1.25', 'colorama==0.3.9', @@ -56,9 +57,11 @@ def get_git_sha(): 'flask-wtf==0.14.2', 'flower==0.9.1', 'future>=0.16.0, <0.17', + 'html5lib==0.999999999', 'humanize==0.5.1', 'gunicorn==19.7.1', 'idna==2.5', + 'lxml==3.8.0', 'markdown==2.6.8', 'pandas==0.20.3', 'parsedatetime==2.0.0', @@ -73,6 +76,7 @@ def get_git_sha(): 'sqlparse==0.2.3', 'thrift>=0.9.3', 'thrift-sasl>=0.2.1', + 'xlrd==1.1.0', ], extras_require={ 'cors': ['Flask-Cors>=2.0.0'],