From 00550d7c02fd47e69700c846c7aeb50585ac2637 Mon Sep 17 00:00:00 2001 From: "Michael S. Molina" <70410625+michael-s-molina@users.noreply.github.com> Date: Wed, 30 Aug 2023 08:45:01 -0300 Subject: [PATCH] fix: Date format when importing international timestamps (#25113) --- .../form_view/csv_to_database_view/edit.html | 229 +++++++++--------- superset/views/database/forms.py | 4 + superset/views/database/views.py | 2 + 3 files changed, 120 insertions(+), 115 deletions(-) diff --git a/superset/templates/superset/form_view/csv_to_database_view/edit.html b/superset/templates/superset/form_view/csv_to_database_view/edit.html index 9bbda3366f458..0ea4b7b0e5fdd 100644 --- a/superset/templates/superset/form_view/csv_to_database_view/edit.html +++ b/superset/templates/superset/form_view/csv_to_database_view/edit.html @@ -1,142 +1,141 @@ -{# - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance - with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, - software distributed under the License is distributed on an - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - KIND, either express or implied. See the License for the - specific language governing permissions and limitations - under the License. -#} -{% extends "appbuilder/base.html" %} -{% import 'appbuilder/general/lib.html' as lib %} -{% import "superset/macros.html" as macros %} -{% set begin_sep_label = '' %} - {% set end_sep_label = '' %} -{% set begin_sep_field = '' %} - {% set end_sep_field = '' %} -{% import 'superset/form_view/database_schemas_selector.html' as schemas_selector %} -{% import 'superset/form_view/csv_scripts.html' as csv_scripts %} -{% import 'superset/form_view/csv_macros.html' as csv_macros %} -{% block content %} -{{ lib.panel_begin(title, "edit") }} +{# Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with this work +for additional information regarding copyright ownership. The ASF licenses this +file to you under the Apache License, Version 2.0 (the "License"); you may not +use this file except in compliance with the License. You may obtain a copy of +the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by +applicable law or agreed to in writing, software distributed under the License +is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the specific language +governing permissions and limitations under the License. #} {% extends +"appbuilder/base.html" %} {% import 'appbuilder/general/lib.html' as lib %} {% +import "superset/macros.html" as macros %} {% set begin_sep_label = ' + + ' %} {% set end_sep_label = ' + +' %} {% set begin_sep_field = ' +' %} {% set end_sep_field = ' +' %} {% import 'superset/form_view/database_schemas_selector.html' as +schemas_selector %} {% import 'superset/form_view/csv_scripts.html' as +csv_scripts %} {% import 'superset/form_view/csv_macros.html' as csv_macros %} +{% block content %} {{ lib.panel_begin(title, "edit") }}
{{form.hidden_tag()}}
-
+
- {{ lib.render_field(form.csv_file, begin_sep_label, end_sep_label, begin_sep_field, end_sep_field) }} + {{ lib.render_field(form.csv_file, begin_sep_label, end_sep_label, + begin_sep_field, end_sep_field) }} - {{ lib.render_field(form.table_name, begin_sep_label, end_sep_label, begin_sep_field, end_sep_field) }} + {{ lib.render_field(form.table_name, begin_sep_label, + end_sep_label, begin_sep_field, end_sep_field) }} - {{ lib.render_field(form.database, begin_sep_label, end_sep_label, begin_sep_field, end_sep_field) }} + {{ lib.render_field(form.database, begin_sep_label, end_sep_label, + begin_sep_field, end_sep_field) }} - {{ lib.render_field(form.schema, begin_sep_label, end_sep_label, begin_sep_field, end_sep_field) }} + {{ lib.render_field(form.schema, begin_sep_label, end_sep_label, + begin_sep_field, end_sep_field) }} - {{ csv_macros.render_delimiter_field(form.delimiter, begin_sep_label, end_sep_label, begin_sep_field, end_sep_field) }} + {{ csv_macros.render_delimiter_field(form.delimiter, + begin_sep_label, end_sep_label, begin_sep_field, end_sep_field) }}
- {% call csv_macros.render_collapsable_form_group("accordion1", "File Settings") %} - - {{ lib.render_field(form.if_exists, begin_sep_label, end_sep_label, begin_sep_field, - end_sep_field) }} - - - {{ lib.render_field(form.skip_initial_space, begin_sep_label, end_sep_label, begin_sep_field, - end_sep_field) }} - - - {{ lib.render_field(form.skip_blank_lines, begin_sep_label, end_sep_label, begin_sep_field, - end_sep_field) }} - - - {{ lib.render_field(form.parse_dates, begin_sep_label, end_sep_label, begin_sep_field, - end_sep_field) }} - - - {{ lib.render_field(form.infer_datetime_format, begin_sep_label, end_sep_label, begin_sep_field, - end_sep_field) }} - - - {{ lib.render_field(form.decimal, begin_sep_label, end_sep_label, begin_sep_field, - end_sep_field) }} - - - {{ lib.render_field(form.null_values, begin_sep_label, end_sep_label, begin_sep_field, - end_sep_field) }} - - {% endcall %} - {% call csv_macros.render_collapsable_form_group("accordion2", "Columns") %} - - {{ lib.render_field(form.index_col, begin_sep_label, end_sep_label, begin_sep_field, - end_sep_field) }} - - - {{ lib.render_field(form.dataframe_index, begin_sep_label, end_sep_label, begin_sep_field, - end_sep_field) }} - - - {{ lib.render_field(form.index_label, begin_sep_label, end_sep_label, begin_sep_field, - end_sep_field) }} - - - {{ lib.render_field(form.use_cols, begin_sep_label, end_sep_label, begin_sep_field, - end_sep_field) }} - - - {{ lib.render_field(form.overwrite_duplicate, begin_sep_label, end_sep_label, begin_sep_field, - end_sep_field) }} - - - {{ lib.render_field(form.dtype, begin_sep_label, end_sep_label, begin_sep_field, - end_sep_field) }} - - {% endcall %} - {% call csv_macros.render_collapsable_form_group("accordion3", "Rows") %} - - {{ lib.render_field(form.header, begin_sep_label, end_sep_label, begin_sep_field, end_sep_field) - }} - - - {{ lib.render_field(form.nrows, begin_sep_label, end_sep_label, begin_sep_field, end_sep_field) - }} - - - {{ lib.render_field(form.skiprows, begin_sep_label, end_sep_label, begin_sep_field, - end_sep_field) }} - + {% call csv_macros.render_collapsable_form_group("accordion1", "File + Settings") %} + + {{ lib.render_field(form.if_exists, begin_sep_label, end_sep_label, + begin_sep_field, end_sep_field) }} + + + {{ lib.render_field(form.skip_initial_space, begin_sep_label, + end_sep_label, begin_sep_field, end_sep_field) }} + + + {{ lib.render_field(form.skip_blank_lines, begin_sep_label, end_sep_label, + begin_sep_field, end_sep_field) }} + + + {{ lib.render_field(form.parse_dates, begin_sep_label, end_sep_label, + begin_sep_field, end_sep_field) }} + + + {{ lib.render_field(form.infer_datetime_format, begin_sep_label, + end_sep_label, begin_sep_field, end_sep_field) }} + + + {{ lib.render_field(form.day_first, begin_sep_label, end_sep_label, + begin_sep_field, end_sep_field) }} + + + {{ lib.render_field(form.decimal, begin_sep_label, end_sep_label, + begin_sep_field, end_sep_field) }} + + + {{ lib.render_field(form.null_values, begin_sep_label, end_sep_label, + begin_sep_field, end_sep_field) }} + + {% endcall %} {% call csv_macros.render_collapsable_form_group("accordion2", + "Columns") %} + + {{ lib.render_field(form.index_col, begin_sep_label, end_sep_label, + begin_sep_field, end_sep_field) }} + + + {{ lib.render_field(form.dataframe_index, begin_sep_label, end_sep_label, + begin_sep_field, end_sep_field) }} + + + {{ lib.render_field(form.index_label, begin_sep_label, end_sep_label, + begin_sep_field, end_sep_field) }} + + + {{ lib.render_field(form.use_cols, begin_sep_label, end_sep_label, + begin_sep_field, end_sep_field) }} + + + {{ lib.render_field(form.overwrite_duplicate, begin_sep_label, + end_sep_label, begin_sep_field, end_sep_field) }} + + + {{ lib.render_field(form.dtype, begin_sep_label, end_sep_label, + begin_sep_field, end_sep_field) }} + + {% endcall %} {% call csv_macros.render_collapsable_form_group("accordion3", + "Rows") %} + + {{ lib.render_field(form.header, begin_sep_label, end_sep_label, + begin_sep_field, end_sep_field) }} + + + {{ lib.render_field(form.nrows, begin_sep_label, end_sep_label, + begin_sep_field, end_sep_field) }} + + + {{ lib.render_field(form.skiprows, begin_sep_label, end_sep_label, + begin_sep_field, end_sep_field) }} + {% endcall %}
-
+
{{ lib.render_form_controls() }}
-{% endblock %} -{% block add_tail_js %} - -{% endblock %} -{% block tail_js %} - {{ super() }} - {{ schemas_selector }} - {{ csv_scripts }} -{% endblock %} +{% endblock %} {% block add_tail_js %} + +{% endblock %} {% block tail_js %} {{ super() }} {{ schemas_selector }} {{ +csv_scripts }} {% endblock %} diff --git a/superset/views/database/forms.py b/superset/views/database/forms.py index 767f4bb4e56cc..36bd43e2fe1a2 100644 --- a/superset/views/database/forms.py +++ b/superset/views/database/forms.py @@ -201,6 +201,10 @@ class CsvToDatabaseForm(UploadToDatabaseForm): _("Interpret Datetime Format Automatically"), description=_("Interpret the datetime format automatically"), ) + day_first = BooleanField( + _("Day First"), + description=_("DD/MM format dates, international and European format"), + ) decimal = StringField( _("Decimal Character"), default=".", diff --git a/superset/views/database/views.py b/superset/views/database/views.py index 43e89bcdf7cb1..6f9344339eaee 100644 --- a/superset/views/database/views.py +++ b/superset/views/database/views.py @@ -168,6 +168,7 @@ def form_get(self, form: CsvToDatabaseForm) -> None: form.skip_initial_space.data = False form.skip_blank_lines.data = True form.infer_datetime_format.data = True + form.day_first.data = False form.decimal.data = "." form.if_exists.data = "fail" @@ -199,6 +200,7 @@ def form_post(self, form: CsvToDatabaseForm) -> Response: header=form.header.data if form.header.data else 0, index_col=form.index_col.data, infer_datetime_format=form.infer_datetime_format.data, + dayfirst=form.day_first.data, iterator=True, keep_default_na=not form.null_values.data, usecols=form.use_cols.data if form.use_cols.data else None,