Repository: PrefectHQ/prefect

Issue:
MySQLFetch throws __enter__
## Description
I just run MySQLFetch task:
```
mysql = MySQLFetch(
        host="...",
        port=3306,
        db_name="...",
        user="...",
        password="...",
        query="SELECT * FROM ... LIMIT 1"
    )
mysql.run()
```
And I get this:
```
Traceback (most recent call last):
  File "/Users/danielnuriyev/simplisafe/scripts/lib/python3.8/site-packages/IPython/core/interactiveshell.py", line 3417, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-2-dfcf3bb3e9b6>", line 1, in <module>
    runfile('/Users/danielnuriyev/test-py/prefect/test.py', wdir='/Users/danielnuriyev/test-py/prefect')
  File "/Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_bundle/pydev_umd.py", line 197, in runfile
    pydev_imports.execfile(filename, global_vars, local_vars)  # execute the script
  File "/Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
  File "/Users/danielnuriyev/test-py/prefect/test.py", line 138, in <module>
    mysql.run()
  File "/Users/danielnuriyev/simplisafe/scripts/lib/python3.8/site-packages/prefect/utilities/tasks.py", line 427, in method
    return run_method(self, *args, **kwargs)
  File "/Users/danielnuriyev/simplisafe/scripts/lib/python3.8/site-packages/prefect/contrib/tasks/mysql/mysql.py", line 211, in run
    raise e
  File "/Users/danielnuriyev/simplisafe/scripts/lib/python3.8/site-packages/prefect/contrib/tasks/mysql/mysql.py", line 187, in run
    with conn:
AttributeError: __enter__
```

I copied MySQLFetch into my code and commented out this line:
https://github.com/PrefectHQ/prefect/blob/master/src/prefect/contrib/tasks/mysql/mysql.py#L79

and the code worked.

## Environment

```json
{
  "config_overrides": {},
  "env_vars": [],
  "system_information": {
    "platform": "macOS-10.15.5-x86_64-i386-64bit",
    "prefect_backend": "server",
    "prefect_version": "0.13.6",
    "python_version": "3.8.2"
  }
}
```
MySQLFetch throws __enter__
## Description
I just run MySQLFetch task:
```
mysql = MySQLFetch(
        host="...",
        port=3306,
        db_name="...",
        user="...",
        password="...",
        query="SELECT * FROM ... LIMIT 1"
    )
mysql.run()
```
And I get this:
```
Traceback (most recent call last):
  File "/Users/danielnuriyev/simplisafe/scripts/lib/python3.8/site-packages/IPython/core/interactiveshell.py", line 3417, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-2-dfcf3bb3e9b6>", line 1, in <module>
    runfile('/Users/danielnuriyev/test-py/prefect/test.py', wdir='/Users/danielnuriyev/test-py/prefect')
  File "/Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_bundle/pydev_umd.py", line 197, in runfile
    pydev_imports.execfile(filename, global_vars, local_vars)  # execute the script
  File "/Applications/PyCharm.app/Contents/plugins/python/helpers/pydev/_pydev_imps/_pydev_execfile.py", line 18, in execfile
    exec(compile(contents+"\n", file, 'exec'), glob, loc)
  File "/Users/danielnuriyev/test-py/prefect/test.py", line 138, in <module>
    mysql.run()
  File "/Users/danielnuriyev/simplisafe/scripts/lib/python3.8/site-packages/prefect/utilities/tasks.py", line 427, in method
    return run_method(self, *args, **kwargs)
  File "/Users/danielnuriyev/simplisafe/scripts/lib/python3.8/site-packages/prefect/contrib/tasks/mysql/mysql.py", line 211, in run
    raise e
  File "/Users/danielnuriyev/simplisafe/scripts/lib/python3.8/site-packages/prefect/contrib/tasks/mysql/mysql.py", line 187, in run
    with conn:
AttributeError: __enter__
```

I copied MySQLFetch into my code and commented out this line:
https://github.com/PrefectHQ/prefect/blob/master/src/prefect/contrib/tasks/mysql/mysql.py#L79

and the code worked.

## Environment

```json
{
  "config_overrides": {},
  "env_vars": [],
  "system_information": {
    "platform": "macOS-10.15.5-x86_64-i386-64bit",
    "prefect_backend": "server",
    "prefect_version": "0.13.6",
    "python_version": "3.8.2"
  }
}
```


Discussion:
Hey @danielnuriyev thanks for catching this! A majority of the tasks in the task library (including this one) are community supported and we encourage contributions! 🙂 
Hey @danielnuriyev thanks for catching this! A majority of the tasks in the task library (including this one) are community supported and we encourage contributions! 🙂 

Resolving patch:
diff --git a/examples/task_library/mysql/mysql_flow.py b/examples/task_library/mysql/mysql_flow.py
new file mode 100644
--- /dev/null
+++ b/examples/task_library/mysql/mysql_flow.py
@@ -0,0 +1,38 @@
+from prefect.tasks.mysql.mysql import MySQLFetch, MySQLExecute
+from prefect import Flow, task
+
+EXAMPLE_TABLE = "user"
+HOST = "localhost"
+PORT = 3306
+DB_NAME = "ext"
+USER = "admin"
+PASSWORD = "admin"
+
+
+mysql_fetch = MySQLFetch(
+    host=HOST, port=PORT, db_name=DB_NAME, user=USER, password=PASSWORD
+)
+
+mysql_exec = MySQLExecute(
+    host=HOST, port=PORT, db_name=DB_NAME, user=USER, password=PASSWORD
+)
+
+
+@task
+def print_results(x):
+    print(x)
+
+
+with Flow("MySQL Example") as flow:
+    # fetch 3 results
+    fetch_results = mysql_fetch(
+        query=f"SELECT * FROM {EXAMPLE_TABLE}", fetch="many", fetch_count=3
+    )
+    print_results(fetch_results)
+
+    # execute a query that returns 3 results
+    exec_results = mysql_exec(query=f"SELECT * FROM {EXAMPLE_TABLE} LIMIT 3")
+    print_results(exec_results)
+
+
+flow.run()
diff --git a/src/prefect/tasks/mysql/mysql.py b/src/prefect/tasks/mysql/mysql.py
--- a/src/prefect/tasks/mysql/mysql.py
+++ b/src/prefect/tasks/mysql/mysql.py
@@ -30,7 +30,7 @@ def __init__(
         user: str,
         password: str,
         host: str,
-        port: int = 3307,
+        port: int = 3306,
         query: str = None,
         commit: bool = False,
         charset: str = "utf8mb4",
@@ -47,9 +47,7 @@ def __init__(
         super().__init__(**kwargs)
 
     @defaults_from_attrs("query", "commit", "charset")
-    def run(
-        self, query: str = None, commit: bool = False, charset: str = "utf8mb4"
-    ) -> int:
+    def run(self, query: str, commit: bool = False, charset: str = "utf8mb4") -> int:
         """
         Task run method. Executes a query against MySQL database.
 
@@ -73,14 +71,14 @@ def run(
             password=self.password,
             db=self.db_name,
             charset=self.charset,
+            port=self.port,
         )
 
         try:
-            with conn:
-                with conn.cursor() as cursor:
-                    executed = cursor.execute(query)
-                    if commit:
-                        conn.commit()
+            with conn.cursor() as cursor:
+                executed = cursor.execute(query)
+                if commit:
+                    conn.commit()
 
             conn.close()
             logging.debug("Execute Results: %s", executed)
@@ -120,7 +118,7 @@ def __init__(
         user: str,
         password: str,
         host: str,
-        port: int = 3307,
+        port: int = 3306,
         fetch: str = "one",
         fetch_count: int = 10,
         query: str = None,
@@ -143,9 +141,9 @@ def __init__(
     @defaults_from_attrs("fetch", "fetch_count", "query", "commit", "charset")
     def run(
         self,
+        query: str,
         fetch: str = "one",
         fetch_count: int = 10,
-        query: str = None,
         commit: bool = False,
         charset: str = "utf8mb4",
     ) -> Any:
@@ -181,25 +179,25 @@ def run(
             password=self.password,
             db=self.db_name,
             charset=self.charset,
+            port=self.port,
         )
 
         try:
-            with conn:
-                with conn.cursor() as cursor:
-                    cursor.execute(query)
-
-                    # override mypy inferred type since we redefine with incompatible types
-                    results: Any
-
-                    if fetch == "all":
-                        results = cursor.fetchall()
-                    elif fetch == "many":
-                        results = cursor.fetchmany(fetch_count)
-                    else:
-                        results = cursor.fetchone()
-
-                    if commit:
-                        conn.commit()
+            with conn.cursor() as cursor:
+                cursor.execute(query)
+
+                # override mypy inferred type since we redefine with incompatible types
+                results: Any
+
+                if fetch == "all":
+                    results = cursor.fetchall()
+                elif fetch == "many":
+                    results = cursor.fetchmany(fetch_count)
+                else:
+                    results = cursor.fetchone()
+
+                if commit:
+                    conn.commit()
 
             conn.close()
             logging.debug("Fetch Results: %s", results)


Test patch: