[ https://issues.apache.org/jira/browse/AIRFLOW-2160?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16381636#comment-16381636 ]
ASF subversion and git services commented on AIRFLOW-2160: ---------------------------------------------------------- Commit a27bd620d97950773c7732908eb3c597315fdd0e in incubator-airflow's branch refs/heads/master from [~cmlad] [ https://git-wip-us.apache.org/repos/asf?p=incubator-airflow.git;h=a27bd62 ] [AIRFLOW-2160] Fix bad rowid deserialization Use Flask-Admin's iterdecode to correctly decode task instance rowids when they contain a dot Closes #3081 from cmlad/fix-bad-rowid- deserialization > Changing task instance state fails when id or execution date contains a dot > --------------------------------------------------------------------------- > > Key: AIRFLOW-2160 > URL: https://issues.apache.org/jira/browse/AIRFLOW-2160 > Project: Apache Airflow > Issue Type: Bug > Components: ui, webapp > Affects Versions: Airflow 2.0, 1.9.1 > Reporter: Christian Mladenov > Assignee: Christian Mladenov > Priority: Minor > > When there is a dot in a task's ID or in its execution date [1], changing its > state from the UI fails. > What the user sees is the non-descript Oops: > {code:java} > ____/ ( ( ) ) \___ > /( ( ( ) _ )) ) )\ > (( ( )( ) ) ( ) ) > ((/ ( _( ) ( _) ) ( () ) ) > ( ( ( (_) (( ( ) .((_ ) . )_ > ( ( ) ( ( ) ) ) . ) ( ) > ( ( ( ( ) ( _ ( _) ). ) . ) ) ( ) > ( ( ( ) ( ) ( )) ) _)( ) ) ) > ( ( ( \ ) ( (_ ( ) ( ) ) ) ) )) ( ) > ( ( ( ( (_ ( ) ( _ ) ) ( ) ) ) > ( ( ( ( ( ) (_ ) ) ) _) ) _( ( ) > (( ( )( ( _ ) _) _(_ ( (_ ) > (_((__(_(__(( ( ( | ) ) ) )_))__))_)___) > ((__) \\||lll|l||/// \_)) > ( /(/ ( ) ) )\ ) > ( ( ( ( | | ) ) )\ ) > ( /(| / ( )) ) ) )) ) > ( ( ((((_(|)_))))) ) > ( ||\(|(|)|/|| ) > ( |(||(||)|||| ) > ( //|/l|||)|\\ \ ) > (/ / // /|//||||\\ \ \ \ _) > ------------------------------------------------------------------------------- > Node: d6b08a99dfda > ------------------------------------------------------------------------------- > Traceback (most recent call last): > File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1982, in > wsgi_app > response = self.full_dispatch_request() > File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1614, in > full_dispatch_request > rv = self.handle_user_exception(e) > File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1517, in > handle_user_exception > reraise(exc_type, exc_value, tb) > File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1612, in > full_dispatch_request > rv = self.dispatch_request() > File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1598, in > dispatch_request > return self.view_functions[rule.endpoint](**req.view_args) > File "/usr/local/lib/python2.7/site-packages/flask_admin/base.py", line 69, > in inner > return self._run_view(f, *args, **kwargs) > File "/usr/local/lib/python2.7/site-packages/flask_admin/base.py", line > 368, in _run_view > return fn(self, *args, **kwargs) > File "/usr/local/lib/python2.7/site-packages/flask_admin/model/base.py", > line 2068, in action_view > return self.handle_action() > File "/usr/local/lib/python2.7/site-packages/flask_admin/actions.py", line > 113, in handle_action > response = handler[0](ids) > File "/usr/local/lib/python2.7/site-packages/airflow/utils/db.py", line 69, > in wrapper > return func(*args, **kwargs) > File "/usr/local/lib/python2.7/site-packages/airflow/www/views.py", line > 2591, in action_clear > raise Exception("Ooops") > Exception: Ooops{code} > The actual exception is something like: > {code:java} > Traceback (most recent call last): > File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1982, in > wsgi_app > response = self.full_dispatch_request() > File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1614, in > full_dispatch_request > rv = self.handle_user_exception(e) > File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1517, in > handle_user_exception > reraise(exc_type, exc_value, tb) > File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1612, in > full_dispatch_request > rv = self.dispatch_request() > File "/usr/local/lib/python2.7/site-packages/flask/app.py", line 1598, in > dispatch_request > return self.view_functions[rule.endpoint](**req.view_args) > File "/usr/local/lib/python2.7/site-packages/flask_admin/base.py", line 69, > in inner > return self._run_view(f, *args, **kwargs) > File "/usr/local/lib/python2.7/site-packages/flask_admin/base.py", line > 368, in _run_view > return fn(self, *args, **kwargs) > File "/usr/local/lib/python2.7/site-packages/flask_admin/model/base.py", > line 2068, in action_view > return self.handle_action() > File "/usr/local/lib/python2.7/site-packages/flask_admin/actions.py", line > 113, in handle_action > response = handler[0](ids) > File "/usr/local/lib/python2.7/site-packages/airflow/utils/db.py", line 69, > in wrapper > return func(*args, **kwargs) > File "/usr/local/lib/python2.7/site-packages/airflow/www/views.py", line > 2573, in action_clear > execution_date = parse_execution_date(execution_date) > File "/usr/local/lib/python2.7/site-packages/airflow/utils/dates.py", line > 247, in parse_execution_date > return timezone.parse(execution_date_str) > File "/usr/local/lib/python2.7/site-packages/airflow/utils/timezone.py", > line 152, in parse > return pendulum.parse(string, tz=TIMEZONE) > File "/usr/local/lib/python2.7/site-packages/pendulum/parser.py", line 75, > in parse > return Parser(**options).parse(text) > File "/usr/local/lib/python2.7/site-packages/pendulum/parser.py", line 31, > in parse > parsed = super(Parser, self).parse(text) > File "/usr/local/lib/python2.7/site-packages/pendulum/parsing/parser.py", > line 297, in parse > return self.normalize(self._parse(text)) > File "/usr/local/lib/python2.7/site-packages/pendulum/parsing/parser.py", > line 355, in _parse > raise ParserError('Invalid date string: {}'.format(text)) > ParserError: Invalid date string: 2018-02-28 20:21:40..819909+00:00{code} > The reason for this is that Flask-Admin's {{iterencode}} function encodes > composite primary keys using dot as the escape symbol. If there is already a > dot in any of the values, it is doubled [2]. > On decoding however, Airflow is currently just splitting the string on a > comma [3]. > The solution would be simple - use Flask-Admin's {{iterdecode}} function > which is already used in another place in views.py [4]. > [1] Dot in the execution date happens when a DAG is run manually. Then the > execution date can contain milliseconds (at least in Postgres) > [2] iterencode escapes a dot with 2 dots: > https://github.com/flask-admin/flask-admin/blob/d57048b041c737f8f4b61f9a2260fc0607dff2aa/flask_admin/tools.py#L118 > [3] > [https://github.com/apache/incubator-airflow/blob/343af062b6426e0e5e5cd1fa2d8c397ad4c626a3/airflow/www/views.py#L2573] > and > [https://github.com/apache/incubator-airflow/blob/343af062b6426e0e5e5cd1fa2d8c397ad4c626a3/airflow/www/views.py#L2607] > [4] > [https://github.com/apache/incubator-airflow/blob/343af062b6426e0e5e5cd1fa2d8c397ad4c626a3/airflow/www/views.py#L2629] > > -- This message was sent by Atlassian JIRA (v7.6.3#76005)