We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
parsl-visualize creates invalid monitoring.db SQL schema
**Describe the bug**
Hi there, and thanks for your support. I'm using HighThroughputExecutor+SlurmProvider to manage my workflow, and I sometimes encounter an unexpected OperationalError when including a MonitoringHub in my Config, which then breaks the monitoring information and also keeps the main python script hanging. The hanging behavior should be related to https://github.com/Parsl/parsl/pull/1917#discussion_r647487589. More generally, I guess that this issue is related to https://github.com/Parsl/parsl/issues/2123 (and indeed I do sometimes have to stop my scripts with ctrl-c, which may have triggered this behavior).

**To Reproduce**
Unfortunately I don't have a minimal working example to show, since (1) this behavior is not reproducible (sometimes the same script does work correctly, sometimes it doesn't), and (2) parsl only enters in a small part of a more complex script that would be useless to fully describe here. Hopefully some parts of the configuration and the logs (below) can be useful to understand what is going wrong.


To configure parsl, I have some trivial auxiliary functions that define a MonitoringHub, a HighThroughputExecutor and a SlurmProvider, for instance like this one:
```
def define_MonitoringHub(workflow_name=None):
    kwargs = dict(
        hub_address=address_by_hostname(),
        monitoring_debug=True,
        resource_monitoring_interval=30,
    )
    if workflow_name is not None:
        kwargs["workflow_name"] = workflow_name
    return MonitoringHub(**kwargs)
```
In the main script, these are called as
```
    provider = define_SlurmProvider(...)
    htex = define_HighThroughputExecutor(provider=provider)
    monitoring = define_MonitoringHub(workflow_name="test")
    config = Config(executors=[htex], monitoring=monitoring)
    parsl.clear()
    parsl.load(config)
```

I let my main script run, and it correctly executes a set of `python_app`'s through SLURM (I see them running with `squeue`, and I verify that the output is correct). After all apps executed, the main script remains hanging, and if I check the logs I see in `runinfo/000/database_manager.log` that the script got stuck in an OperationalError loop:
```
$ tail -n 8 runinfo/000/database_manager.log 
2022-05-30 10:34:02.599 database_manager:597 [WARNING] [MainThread 140641839281920] Got a database OperationalError. Ignoring and retrying on the assumption that it is recoverable: (sqlite3.OperationalError) table task has no column named task_time_invoked
[SQL: INSERT INTO task (task_id, run_id, task_depends, task_func_name, task_memoize, task_inputs, task_outputs, task_time_invoked, task_fail_count, task_fail_cost) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)]
[parameters: (0, '903cd6fa-cda7-416d-9ada-bdeb09a030d2', '', 'app_create_zarr_structure', False, 'None', 'None', '2022-05-30 10:28:28.462702', 0, 0.0)]
(Background on this error at: http://sqlalche.me/e/13/e3q8)
2022-05-30 10:34:03.604 database_manager:597 [WARNING] [MainThread 140641839281920] Got a database OperationalError. Ignoring and retrying on the assumption that it is recoverable: (sqlite3.OperationalError) table task has no column named task_time_invoked
[SQL: INSERT INTO task (task_id, run_id, task_depends, task_func_name, task_memoize, task_inputs, task_outputs, task_time_invoked, task_fail_count, task_fail_cost) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)]
[parameters: (0, '903cd6fa-cda7-416d-9ada-bdeb09a030d2', '', 'app_create_zarr_structure', False, 'None', 'None', '2022-05-30 10:28:28.462702', 0, 0.0)]
(Background on this error at: http://sqlalche.me/e/13/e3q8)
```
where it just prints this error message once per second. I attach the full `database_manager.log`, `monitoring_router.log` and `parsl.log`. You see that `parsl.log` is missing the final "DFK cleanup complete" cleanup line (which is present for cases that run smoothly).

[database_manager.log](https://github.com/Parsl/parsl/files/8798140/database_manager.log)
[monitoring_router.log](https://github.com/Parsl/parsl/files/8798141/monitoring_router.log)
[parsl.log](https://github.com/Parsl/parsl/files/8798142/parsl.log)



After this situation takes place, re-running the same script typically leads to the same behavior, even if I remove `monitoring.db` and the `runinfo` folder (which is puzzling.. is there a state of the DFK which somehow remains active after I kill the python script?), although sometimes I recover the expected correct behavior.
Meanwhile, these "wrong" runs cannot be accessed through `parsl-visualize` (when I select a workflow in the web interface, I either get "500 Internal server error" or "Workflow 903cd6fa-cda7-416d-9ada-bdeb09a030d2 does not have any resource usage records. ") , but this is not surprising given that the database is probably corrupted somewhere.


**Expected behavior**
I expected no OperationalError, as the `task_time_invoked` column should be present.

**Environment**
 - OS: OS: Ubuntu 16
 - Python version: 3.8.13
 - Parsl version: 1.2.0

**Distributed Environment**
- Where are you running the Parsl script from ? Login node
- Where do you need the workers to run ? Compute nodes

(apologies for the non-reproducible issue description, I'll keep trying to make the unexpected behavior more robust)

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `parsl/monitoring/visualization/models.py`
Content:
```
1 from flask_sqlalchemy import SQLAlchemy
2 
3 
4 WORKFLOW = 'workflow'    # Workflow table includes workflow metadata
5 TASK = 'task'            # Task table includes task metadata
6 STATUS = 'status'        # Status table includes task status
7 RESOURCE = 'resource'    # Resource table includes task resource utilization
8 NODE = 'node'            # Node table include node info
9 
10 db = SQLAlchemy()
11 
12 
13 class Workflow(db.Model):
14     __tablename__ = WORKFLOW
15     run_id = db.Column(db.Text, nullable=False, primary_key=True)
16     workflow_name = db.Column(db.Text, nullable=True)
17     workflow_version = db.Column(db.Text, nullable=True)
18     time_began = db.Column(db.DateTime, nullable=False)  # Why not date?
19     time_completed = db.Column(db.DateTime)
20     host = db.Column(db.Text, nullable=False)
21     user = db.Column(db.Text, nullable=False)
22     rundir = db.Column(db.Text, nullable=False)
23     tasks_failed_count = db.Column(db.Integer, nullable=False)
24     tasks_completed_count = db.Column(db.Integer, nullable=False)
25 
26 
27 class Node(db.Model):
28     __tablename__ = NODE
29     id = db.Column('id', db.Integer, nullable=False, primary_key=True, autoincrement=True)
30     run_id = db.Column('run_id', db.Text, nullable=False)
31     hostname = db.Column('hostname', db.Text, nullable=False)
32     cpu_count = db.Column('cpu_count', db.Integer, nullable=False)
33     total_memory = db.Column('total_memory', db.Integer, nullable=False)
34     active = db.Column('active', db.Boolean, nullable=False)
35     worker_count = db.Column('worker_count', db.Integer, nullable=False)
36     python_v = db.Column('python_v', db.Text, nullable=False)
37     reg_time = db.Column('reg_time', db.DateTime, nullable=False)
38 
39 
40 # TODO: expand to full set of info
41 class Status(db.Model):
42     __tablename__ = STATUS
43     task_id = db.Column(db.Integer, db.ForeignKey(
44         'task.task_id'), nullable=False)
45     task_status_name = db.Column(db.Text, nullable=False)
46     timestamp = db.Column(db.DateTime, nullable=False)
47     run_id = db.Column(db.Text, db.ForeignKey(
48         'workflow.run_id'), nullable=False)
49     __table_args__ = (
50         db.PrimaryKeyConstraint('task_id', 'run_id',
51                                 'task_status_name', 'timestamp'),
52     )
53 
54 
55 class Task(db.Model):
56     __tablename__ = TASK
57     task_id = db.Column('task_id', db.Integer, nullable=False)
58     run_id = db.Column('run_id', db.Text, nullable=False)
59     task_func_name = db.Column('task_func_name', db.Text, nullable=False)
60     task_depends = db.Column('task_depends', db.Text, nullable=True)
61     task_time_returned = db.Column(
62         'task_time_returned', db.DateTime, nullable=True)
63     task_memoize = db.Column('task_memoize', db.Text, nullable=False)
64     task_inputs = db.Column('task_inputs', db.Text, nullable=True)
65     task_outputs = db.Column('task_outputs', db.Text, nullable=True)
66     task_stdin = db.Column('task_stdin', db.Text, nullable=True)
67     task_stdout = db.Column('task_stdout', db.Text, nullable=True)
68     task_stderr = db.Column('task_stderr', db.Text, nullable=True)
69     __table_args__ = (
70         db.PrimaryKeyConstraint('task_id', 'run_id'),
71     )
72 
73 
74 class Resource(db.Model):
75     __tablename__ = RESOURCE
76     task_id = db.Column('task_id', db.Integer, db.ForeignKey(
77         'task.task_id'), nullable=False)
78     timestamp = db.Column('timestamp', db.DateTime, nullable=False)
79     run_id = db.Column('run_id', db.Text, db.ForeignKey(
80         'workflow.run_id'), nullable=False)
81     resource_monitoring_interval = db.Column(
82         'resource_monitoring_interval', db.Float, nullable=True)
83     psutil_process_pid = db.Column(
84         'psutil_process_pid', db.Integer, nullable=True)
85     psutil_process_memory_percent = db.Column(
86         'psutil_process_memory_percent', db.Float, nullable=True)
87     psutil_process_children_count = db.Column(
88         'psutil_process_children_count', db.Float, nullable=True)
89     psutil_process_time_user = db.Column(
90         'psutil_process_time_user', db.Float, nullable=True)
91     psutil_process_time_system = db.Column(
92         'psutil_process_time_system', db.Float, nullable=True)
93     psutil_process_memory_virtual = db.Column(
94         'psutil_process_memory_virtual', db.Float, nullable=True)
95     psutil_process_memory_resident = db.Column(
96         'psutil_process_memory_resident', db.Float, nullable=True)
97     psutil_process_disk_read = db.Column(
98         'psutil_process_disk_read', db.Float, nullable=True)
99     psutil_process_disk_write = db.Column(
100         'psutil_process_disk_write', db.Float, nullable=True)
101     psutil_process_status = db.Column(
102         'psutil_process_status', db.Text, nullable=True)
103     __table_args__ = (
104         db.PrimaryKeyConstraint('task_id', 'run_id', 'timestamp'),)
105
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/parsl/monitoring/visualization/models.py b/parsl/monitoring/visualization/models.py
--- a/parsl/monitoring/visualization/models.py
+++ b/parsl/monitoring/visualization/models.py
@@ -58,6 +58,8 @@
     run_id = db.Column('run_id', db.Text, nullable=False)
     task_func_name = db.Column('task_func_name', db.Text, nullable=False)
     task_depends = db.Column('task_depends', db.Text, nullable=True)
+    task_time_invoked = db.Column(
+        'task_time_invoked', db.DateTime, nullable=True)
     task_time_returned = db.Column(
         'task_time_returned', db.DateTime, nullable=True)
     task_memoize = db.Column('task_memoize', db.Text, nullable=False)

{"golden_diff": "diff --git a/parsl/monitoring/visualization/models.py b/parsl/monitoring/visualization/models.py\n--- a/parsl/monitoring/visualization/models.py\n+++ b/parsl/monitoring/visualization/models.py\n@@ -58,6 +58,8 @@\n     run_id = db.Column('run_id', db.Text, nullable=False)\n     task_func_name = db.Column('task_func_name', db.Text, nullable=False)\n     task_depends = db.Column('task_depends', db.Text, nullable=True)\n+    task_time_invoked = db.Column(\n+        'task_time_invoked', db.DateTime, nullable=True)\n     task_time_returned = db.Column(\n         'task_time_returned', db.DateTime, nullable=True)\n     task_memoize = db.Column('task_memoize', db.Text, nullable=False)\n", "issue": "parsl-visualize creates invalid monitoring.db SQL schema\n**Describe the bug**\r\nHi there, and thanks for your support. I'm using HighThroughputExecutor+SlurmProvider to manage my workflow, and I sometimes encounter an unexpected OperationalError when including a MonitoringHub in my Config, which then breaks the monitoring information and also keeps the main python script hanging. The hanging behavior should be related to https://github.com/Parsl/parsl/pull/1917#discussion_r647487589. More generally, I guess that this issue is related to https://github.com/Parsl/parsl/issues/2123 (and indeed I do sometimes have to stop my scripts with ctrl-c, which may have triggered this behavior).\r\n\r\n**To Reproduce**\r\nUnfortunately I don't have a minimal working example to show, since (1) this behavior is not reproducible (sometimes the same script does work correctly, sometimes it doesn't), and (2) parsl only enters in a small part of a more complex script that would be useless to fully describe here. Hopefully some parts of the configuration and the logs (below) can be useful to understand what is going wrong.\r\n\r\n\r\nTo configure parsl, I have some trivial auxiliary functions that define a MonitoringHub, a HighThroughputExecutor and a SlurmProvider, for instance like this one:\r\n```\r\ndef define_MonitoringHub(workflow_name=None):\r\n    kwargs = dict(\r\n        hub_address=address_by_hostname(),\r\n        monitoring_debug=True,\r\n        resource_monitoring_interval=30,\r\n    )\r\n    if workflow_name is not None:\r\n        kwargs[\"workflow_name\"] = workflow_name\r\n    return MonitoringHub(**kwargs)\r\n```\r\nIn the main script, these are called as\r\n```\r\n    provider = define_SlurmProvider(...)\r\n    htex = define_HighThroughputExecutor(provider=provider)\r\n    monitoring = define_MonitoringHub(workflow_name=\"test\")\r\n    config = Config(executors=[htex], monitoring=monitoring)\r\n    parsl.clear()\r\n    parsl.load(config)\r\n```\r\n\r\nI let my main script run, and it correctly executes a set of `python_app`'s through SLURM (I see them running with `squeue`, and I verify that the output is correct). After all apps executed, the main script remains hanging, and if I check the logs I see in `runinfo/000/database_manager.log` that the script got stuck in an OperationalError loop:\r\n```\r\n$ tail -n 8 runinfo/000/database_manager.log \r\n2022-05-30 10:34:02.599 database_manager:597 [WARNING] [MainThread 140641839281920] Got a database OperationalError. Ignoring and retrying on the assumption that it is recoverable: (sqlite3.OperationalError) table task has no column named task_time_invoked\r\n[SQL: INSERT INTO task (task_id, run_id, task_depends, task_func_name, task_memoize, task_inputs, task_outputs, task_time_invoked, task_fail_count, task_fail_cost) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)]\r\n[parameters: (0, '903cd6fa-cda7-416d-9ada-bdeb09a030d2', '', 'app_create_zarr_structure', False, 'None', 'None', '2022-05-30 10:28:28.462702', 0, 0.0)]\r\n(Background on this error at: http://sqlalche.me/e/13/e3q8)\r\n2022-05-30 10:34:03.604 database_manager:597 [WARNING] [MainThread 140641839281920] Got a database OperationalError. Ignoring and retrying on the assumption that it is recoverable: (sqlite3.OperationalError) table task has no column named task_time_invoked\r\n[SQL: INSERT INTO task (task_id, run_id, task_depends, task_func_name, task_memoize, task_inputs, task_outputs, task_time_invoked, task_fail_count, task_fail_cost) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)]\r\n[parameters: (0, '903cd6fa-cda7-416d-9ada-bdeb09a030d2', '', 'app_create_zarr_structure', False, 'None', 'None', '2022-05-30 10:28:28.462702', 0, 0.0)]\r\n(Background on this error at: http://sqlalche.me/e/13/e3q8)\r\n```\r\nwhere it just prints this error message once per second. I attach the full `database_manager.log`, `monitoring_router.log` and `parsl.log`. You see that `parsl.log` is missing the final \"DFK cleanup complete\" cleanup line (which is present for cases that run smoothly).\r\n\r\n[database_manager.log](https://github.com/Parsl/parsl/files/8798140/database_manager.log)\r\n[monitoring_router.log](https://github.com/Parsl/parsl/files/8798141/monitoring_router.log)\r\n[parsl.log](https://github.com/Parsl/parsl/files/8798142/parsl.log)\r\n\r\n\r\n\r\nAfter this situation takes place, re-running the same script typically leads to the same behavior, even if I remove `monitoring.db` and the `runinfo` folder (which is puzzling.. is there a state of the DFK which somehow remains active after I kill the python script?), although sometimes I recover the expected correct behavior.\r\nMeanwhile, these \"wrong\" runs cannot be accessed through `parsl-visualize` (when I select a workflow in the web interface, I either get \"500 Internal server error\" or \"Workflow 903cd6fa-cda7-416d-9ada-bdeb09a030d2 does not have any resource usage records. \") , but this is not surprising given that the database is probably corrupted somewhere.\r\n\r\n\r\n**Expected behavior**\r\nI expected no OperationalError, as the `task_time_invoked` column should be present.\r\n\r\n**Environment**\r\n - OS: OS: Ubuntu 16\r\n - Python version: 3.8.13\r\n - Parsl version: 1.2.0\r\n\r\n**Distributed Environment**\r\n- Where are you running the Parsl script from ? Login node\r\n- Where do you need the workers to run ? Compute nodes\r\n\r\n(apologies for the non-reproducible issue description, I'll keep trying to make the unexpected behavior more robust)\n", "before_files": [{"content": "from flask_sqlalchemy import SQLAlchemy\n\n\nWORKFLOW = 'workflow'    # Workflow table includes workflow metadata\nTASK = 'task'            # Task table includes task metadata\nSTATUS = 'status'        # Status table includes task status\nRESOURCE = 'resource'    # Resource table includes task resource utilization\nNODE = 'node'            # Node table include node info\n\ndb = SQLAlchemy()\n\n\nclass Workflow(db.Model):\n    __tablename__ = WORKFLOW\n    run_id = db.Column(db.Text, nullable=False, primary_key=True)\n    workflow_name = db.Column(db.Text, nullable=True)\n    workflow_version = db.Column(db.Text, nullable=True)\n    time_began = db.Column(db.DateTime, nullable=False)  # Why not date?\n    time_completed = db.Column(db.DateTime)\n    host = db.Column(db.Text, nullable=False)\n    user = db.Column(db.Text, nullable=False)\n    rundir = db.Column(db.Text, nullable=False)\n    tasks_failed_count = db.Column(db.Integer, nullable=False)\n    tasks_completed_count = db.Column(db.Integer, nullable=False)\n\n\nclass Node(db.Model):\n    __tablename__ = NODE\n    id = db.Column('id', db.Integer, nullable=False, primary_key=True, autoincrement=True)\n    run_id = db.Column('run_id', db.Text, nullable=False)\n    hostname = db.Column('hostname', db.Text, nullable=False)\n    cpu_count = db.Column('cpu_count', db.Integer, nullable=False)\n    total_memory = db.Column('total_memory', db.Integer, nullable=False)\n    active = db.Column('active', db.Boolean, nullable=False)\n    worker_count = db.Column('worker_count', db.Integer, nullable=False)\n    python_v = db.Column('python_v', db.Text, nullable=False)\n    reg_time = db.Column('reg_time', db.DateTime, nullable=False)\n\n\n# TODO: expand to full set of info\nclass Status(db.Model):\n    __tablename__ = STATUS\n    task_id = db.Column(db.Integer, db.ForeignKey(\n        'task.task_id'), nullable=False)\n    task_status_name = db.Column(db.Text, nullable=False)\n    timestamp = db.Column(db.DateTime, nullable=False)\n    run_id = db.Column(db.Text, db.ForeignKey(\n        'workflow.run_id'), nullable=False)\n    __table_args__ = (\n        db.PrimaryKeyConstraint('task_id', 'run_id',\n                                'task_status_name', 'timestamp'),\n    )\n\n\nclass Task(db.Model):\n    __tablename__ = TASK\n    task_id = db.Column('task_id', db.Integer, nullable=False)\n    run_id = db.Column('run_id', db.Text, nullable=False)\n    task_func_name = db.Column('task_func_name', db.Text, nullable=False)\n    task_depends = db.Column('task_depends', db.Text, nullable=True)\n    task_time_returned = db.Column(\n        'task_time_returned', db.DateTime, nullable=True)\n    task_memoize = db.Column('task_memoize', db.Text, nullable=False)\n    task_inputs = db.Column('task_inputs', db.Text, nullable=True)\n    task_outputs = db.Column('task_outputs', db.Text, nullable=True)\n    task_stdin = db.Column('task_stdin', db.Text, nullable=True)\n    task_stdout = db.Column('task_stdout', db.Text, nullable=True)\n    task_stderr = db.Column('task_stderr', db.Text, nullable=True)\n    __table_args__ = (\n        db.PrimaryKeyConstraint('task_id', 'run_id'),\n    )\n\n\nclass Resource(db.Model):\n    __tablename__ = RESOURCE\n    task_id = db.Column('task_id', db.Integer, db.ForeignKey(\n        'task.task_id'), nullable=False)\n    timestamp = db.Column('timestamp', db.DateTime, nullable=False)\n    run_id = db.Column('run_id', db.Text, db.ForeignKey(\n        'workflow.run_id'), nullable=False)\n    resource_monitoring_interval = db.Column(\n        'resource_monitoring_interval', db.Float, nullable=True)\n    psutil_process_pid = db.Column(\n        'psutil_process_pid', db.Integer, nullable=True)\n    psutil_process_memory_percent = db.Column(\n        'psutil_process_memory_percent', db.Float, nullable=True)\n    psutil_process_children_count = db.Column(\n        'psutil_process_children_count', db.Float, nullable=True)\n    psutil_process_time_user = db.Column(\n        'psutil_process_time_user', db.Float, nullable=True)\n    psutil_process_time_system = db.Column(\n        'psutil_process_time_system', db.Float, nullable=True)\n    psutil_process_memory_virtual = db.Column(\n        'psutil_process_memory_virtual', db.Float, nullable=True)\n    psutil_process_memory_resident = db.Column(\n        'psutil_process_memory_resident', db.Float, nullable=True)\n    psutil_process_disk_read = db.Column(\n        'psutil_process_disk_read', db.Float, nullable=True)\n    psutil_process_disk_write = db.Column(\n        'psutil_process_disk_write', db.Float, nullable=True)\n    psutil_process_status = db.Column(\n        'psutil_process_status', db.Text, nullable=True)\n    __table_args__ = (\n        db.PrimaryKeyConstraint('task_id', 'run_id', 'timestamp'),)\n", "path": "parsl/monitoring/visualization/models.py"}], "after_files": [{"content": "from flask_sqlalchemy import SQLAlchemy\n\n\nWORKFLOW = 'workflow'    # Workflow table includes workflow metadata\nTASK = 'task'            # Task table includes task metadata\nSTATUS = 'status'        # Status table includes task status\nRESOURCE = 'resource'    # Resource table includes task resource utilization\nNODE = 'node'            # Node table include node info\n\ndb = SQLAlchemy()\n\n\nclass Workflow(db.Model):\n    __tablename__ = WORKFLOW\n    run_id = db.Column(db.Text, nullable=False, primary_key=True)\n    workflow_name = db.Column(db.Text, nullable=True)\n    workflow_version = db.Column(db.Text, nullable=True)\n    time_began = db.Column(db.DateTime, nullable=False)  # Why not date?\n    time_completed = db.Column(db.DateTime)\n    host = db.Column(db.Text, nullable=False)\n    user = db.Column(db.Text, nullable=False)\n    rundir = db.Column(db.Text, nullable=False)\n    tasks_failed_count = db.Column(db.Integer, nullable=False)\n    tasks_completed_count = db.Column(db.Integer, nullable=False)\n\n\nclass Node(db.Model):\n    __tablename__ = NODE\n    id = db.Column('id', db.Integer, nullable=False, primary_key=True, autoincrement=True)\n    run_id = db.Column('run_id', db.Text, nullable=False)\n    hostname = db.Column('hostname', db.Text, nullable=False)\n    cpu_count = db.Column('cpu_count', db.Integer, nullable=False)\n    total_memory = db.Column('total_memory', db.Integer, nullable=False)\n    active = db.Column('active', db.Boolean, nullable=False)\n    worker_count = db.Column('worker_count', db.Integer, nullable=False)\n    python_v = db.Column('python_v', db.Text, nullable=False)\n    reg_time = db.Column('reg_time', db.DateTime, nullable=False)\n\n\n# TODO: expand to full set of info\nclass Status(db.Model):\n    __tablename__ = STATUS\n    task_id = db.Column(db.Integer, db.ForeignKey(\n        'task.task_id'), nullable=False)\n    task_status_name = db.Column(db.Text, nullable=False)\n    timestamp = db.Column(db.DateTime, nullable=False)\n    run_id = db.Column(db.Text, db.ForeignKey(\n        'workflow.run_id'), nullable=False)\n    __table_args__ = (\n        db.PrimaryKeyConstraint('task_id', 'run_id',\n                                'task_status_name', 'timestamp'),\n    )\n\n\nclass Task(db.Model):\n    __tablename__ = TASK\n    task_id = db.Column('task_id', db.Integer, nullable=False)\n    run_id = db.Column('run_id', db.Text, nullable=False)\n    task_func_name = db.Column('task_func_name', db.Text, nullable=False)\n    task_depends = db.Column('task_depends', db.Text, nullable=True)\n    task_time_invoked = db.Column(\n        'task_time_invoked', db.DateTime, nullable=True)\n    task_time_returned = db.Column(\n        'task_time_returned', db.DateTime, nullable=True)\n    task_memoize = db.Column('task_memoize', db.Text, nullable=False)\n    task_inputs = db.Column('task_inputs', db.Text, nullable=True)\n    task_outputs = db.Column('task_outputs', db.Text, nullable=True)\n    task_stdin = db.Column('task_stdin', db.Text, nullable=True)\n    task_stdout = db.Column('task_stdout', db.Text, nullable=True)\n    task_stderr = db.Column('task_stderr', db.Text, nullable=True)\n    __table_args__ = (\n        db.PrimaryKeyConstraint('task_id', 'run_id'),\n    )\n\n\nclass Resource(db.Model):\n    __tablename__ = RESOURCE\n    task_id = db.Column('task_id', db.Integer, db.ForeignKey(\n        'task.task_id'), nullable=False)\n    timestamp = db.Column('timestamp', db.DateTime, nullable=False)\n    run_id = db.Column('run_id', db.Text, db.ForeignKey(\n        'workflow.run_id'), nullable=False)\n    resource_monitoring_interval = db.Column(\n        'resource_monitoring_interval', db.Float, nullable=True)\n    psutil_process_pid = db.Column(\n        'psutil_process_pid', db.Integer, nullable=True)\n    psutil_process_memory_percent = db.Column(\n        'psutil_process_memory_percent', db.Float, nullable=True)\n    psutil_process_children_count = db.Column(\n        'psutil_process_children_count', db.Float, nullable=True)\n    psutil_process_time_user = db.Column(\n        'psutil_process_time_user', db.Float, nullable=True)\n    psutil_process_time_system = db.Column(\n        'psutil_process_time_system', db.Float, nullable=True)\n    psutil_process_memory_virtual = db.Column(\n        'psutil_process_memory_virtual', db.Float, nullable=True)\n    psutil_process_memory_resident = db.Column(\n        'psutil_process_memory_resident', db.Float, nullable=True)\n    psutil_process_disk_read = db.Column(\n        'psutil_process_disk_read', db.Float, nullable=True)\n    psutil_process_disk_write = db.Column(\n        'psutil_process_disk_write', db.Float, nullable=True)\n    psutil_process_status = db.Column(\n        'psutil_process_status', db.Text, nullable=True)\n    __table_args__ = (\n        db.PrimaryKeyConstraint('task_id', 'run_id', 'timestamp'),)\n", "path": "parsl/monitoring/visualization/models.py"}]}