forms: make csv import parse dates accepts a list of columns (#4639)
Instead of a boolean which has way less chances to work. While at it add a proper label for the "con" field. Fixes #4637
This commit is contained in:
parent
f11cde9eb8
commit
76394d3f8f
|
|
@ -10,7 +10,7 @@ from flask_appbuilder.forms import DynamicForm
|
||||||
from flask_babel import lazy_gettext as _
|
from flask_babel import lazy_gettext as _
|
||||||
from flask_wtf.file import FileAllowed, FileField, FileRequired
|
from flask_wtf.file import FileAllowed, FileField, FileRequired
|
||||||
from wtforms import (
|
from wtforms import (
|
||||||
BooleanField, IntegerField, SelectField, StringField)
|
BooleanField, Field, IntegerField, SelectField, StringField)
|
||||||
from wtforms.ext.sqlalchemy.fields import QuerySelectField
|
from wtforms.ext.sqlalchemy.fields import QuerySelectField
|
||||||
from wtforms.validators import DataRequired, NumberRange, Optional
|
from wtforms.validators import DataRequired, NumberRange, Optional
|
||||||
|
|
||||||
|
|
@ -20,6 +20,32 @@ from superset.models import core as models
|
||||||
config = app.config
|
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):
|
class CsvToDatabaseForm(DynamicForm):
|
||||||
# pylint: disable=E0211
|
# pylint: disable=E0211
|
||||||
def all_db_items():
|
def all_db_items():
|
||||||
|
|
@ -36,6 +62,7 @@ class CsvToDatabaseForm(DynamicForm):
|
||||||
validators=[
|
validators=[
|
||||||
FileRequired(), FileAllowed(['csv'], _('CSV Files Only!'))])
|
FileRequired(), FileAllowed(['csv'], _('CSV Files Only!'))])
|
||||||
con = QuerySelectField(
|
con = QuerySelectField(
|
||||||
|
_('Database'),
|
||||||
query_factory=all_db_items,
|
query_factory=all_db_items,
|
||||||
get_pk=lambda a: a.id, get_label=lambda a: a.database_name)
|
get_pk=lambda a: a.id, get_label=lambda a: a.database_name)
|
||||||
sep = StringField(
|
sep = StringField(
|
||||||
|
|
@ -99,9 +126,12 @@ class CsvToDatabaseForm(DynamicForm):
|
||||||
description=_(
|
description=_(
|
||||||
'Skip blank lines rather than interpreting them '
|
'Skip blank lines rather than interpreting them '
|
||||||
'as NaN values.'))
|
'as NaN values.'))
|
||||||
parse_dates = BooleanField(
|
parse_dates = CommaSeparatedListField(
|
||||||
_('Parse Dates'),
|
_('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 = BooleanField(
|
||||||
_('Infer Datetime Format'),
|
_('Infer Datetime Format'),
|
||||||
description=_(
|
description=_(
|
||||||
|
|
|
||||||
|
|
@ -339,7 +339,6 @@ class CsvToDatabaseView(SimpleFormView):
|
||||||
form.mangle_dupe_cols.data = True
|
form.mangle_dupe_cols.data = True
|
||||||
form.skipinitialspace.data = False
|
form.skipinitialspace.data = False
|
||||||
form.skip_blank_lines.data = True
|
form.skip_blank_lines.data = True
|
||||||
form.parse_dates.data = True
|
|
||||||
form.infer_datetime_format.data = True
|
form.infer_datetime_format.data = True
|
||||||
form.decimal.data = '.'
|
form.decimal.data = '.'
|
||||||
form.if_exists.data = 'append'
|
form.if_exists.data = 'append'
|
||||||
|
|
|
||||||
|
|
@ -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'])
|
||||||
Loading…
Reference in New Issue