Skip to content
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

forms: make csv import parse dates accepts a list of columns #4639

Merged
merged 1 commit into from
Mar 23, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 33 additions & 3 deletions superset/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from flask_babel import lazy_gettext as _
from flask_wtf.file import FileAllowed, FileField, FileRequired
from wtforms import (
BooleanField, IntegerField, SelectField, StringField)
BooleanField, Field, IntegerField, SelectField, StringField)
from wtforms.ext.sqlalchemy.fields import QuerySelectField
from wtforms.validators import DataRequired, NumberRange, Optional

Expand All @@ -20,6 +20,32 @@
config = app.config


class CommaSeparatedListField(Field):
widget = BS3TextFieldWidget()

def _value(self):
if self.data:
return u', '.join(self.data)
else:
return u''

def process_formdata(self, valuelist):
if valuelist:
self.data = [x.strip() for x in valuelist[0].split(',')]
else:
self.data = []


def filter_not_empty_values(value):
"""Returns a list of non empty values or None"""
if not value:
return None
data = [x for x in value if x]
if not data:
return None
return data


class CsvToDatabaseForm(DynamicForm):
# pylint: disable=E0211
def all_db_items():
Expand All @@ -36,6 +62,7 @@ def all_db_items():
validators=[
FileRequired(), FileAllowed(['csv'], _('CSV Files Only!'))])
con = QuerySelectField(
_('Database'),
query_factory=all_db_items,
get_pk=lambda a: a.id, get_label=lambda a: a.database_name)
sep = StringField(
Expand Down Expand Up @@ -99,9 +126,12 @@ def all_db_items():
description=_(
'Skip blank lines rather than interpreting them '
'as NaN values.'))
parse_dates = BooleanField(
parse_dates = CommaSeparatedListField(
_('Parse Dates'),
description=_('Parse date values.'))
description=_(
'A comma separated list of columns that should be '
'parsed as dates.'),
filters=[filter_not_empty_values])
infer_datetime_format = BooleanField(
_('Infer Datetime Format'),
description=_(
Expand Down
1 change: 0 additions & 1 deletion superset/views/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,6 @@ def form_get(self, form):
form.mangle_dupe_cols.data = True
form.skipinitialspace.data = False
form.skip_blank_lines.data = True
form.parse_dates.data = True
form.infer_datetime_format.data = True
form.decimal.data = '.'
form.if_exists.data = 'append'
Expand Down
28 changes: 28 additions & 0 deletions tests/form_tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

from tests.base_tests import SupersetTestCase
from wtforms.form import Form

from superset.forms import (
CommaSeparatedListField, filter_not_empty_values)


class FormTestCase(SupersetTestCase):

def test_comma_separated_list_field(self):
field = CommaSeparatedListField().bind(Form(), 'foo')
field.process_formdata([u''])
self.assertEqual(field.data, [u''])

field.process_formdata(['a,comma,separated,list'])
self.assertEqual(field.data, [u'a', u'comma', u'separated', u'list'])

def test_filter_not_empty_values(self):
self.assertEqual(filter_not_empty_values(None), None)
self.assertEqual(filter_not_empty_values([]), None)
self.assertEqual(filter_not_empty_values(['']), None)
self.assertEqual(filter_not_empty_values(['hi']), ['hi'])