\$\begingroup\$
\$\endgroup\$
I have written this code that connects to a mysql database. The function should be able to be used as a context manager - via with
. It is working, but I am not sure if this is a great way of doing it.
conect.py
import os
import mysql.connector
from mysql.connector import errorcode
import contextlib
_CFG = {
'user': os.getenv("MYSQL_USER"),
'password': os.getenv("MYSQL_PASSWORD"),
'host': os.getenv("MYSQL_SERVER"),
'database': os.getenv("SENSOR_DB"),
'raise_on_warnings': True
}
@contextlib.contextmanager
def _connect(db=None):
if db:
_CFG["database"] = db
try:
print("{usr} connecting to {db} on {host}.".format(
usr=_CFG["user"],
db=_CFG["database"],
host=_CFG["host"]
)
)
connection = mysql.connector.connect(**_CFG)
yield connection
except mysql.connector.Error as err:
if err.errno == errorcode.ER_ACCESS_DENIED_ERROR:
print("Something is wrong with your user name or password")
elif err.errno == errorcode.ER_BAD_DB_ERROR:
print("Database does not exist")
else:
print(err)
yield None
else:
connection.commit()
finally:
connection.close()
asked Jan 21, 2020 at 20:10
1 Answer 1
\$\begingroup\$
\$\endgroup\$
3
- Obvious (dumb) point - I'd suggest using
logging
instead ofprint
- I would have some kind of builder for
_CFG
so I could choose if I use environment variables for configuration or something else - Instead of
str.format
, you may want to use fstring:f"{_CFG["user"]} connecting to {_CFG["database"]} on {_CFG["host"]}."
- Instead of
yield None
you may want to reraise exception (from the docs, "If an exception is trapped merely in order to log it or to perform some action (rather than to suppress it entirely), the generator must reraise that exception"). Otherwise, your code will fail with a funny exception.
Toby Speight
87.9k14 gold badges104 silver badges325 bronze badges
answered Jan 22, 2020 at 17:28
-
\$\begingroup\$ I was wondering even if the
_connect
function acts as context manger , should I just call it at module level instead of usingwith
inside a function, then the connection object will be available at multiple functions ? \$\endgroup\$Ciasto piekarz– Ciasto piekarz2020年01月26日 18:43:58 +00:00Commented Jan 26, 2020 at 18:43 -
\$\begingroup\$ @Ciastopiekarz I think that if you want to have a shared connection in multiple functions, you would rather not use a context manager at all, but some other patterns to handle this. But why would you want this? I would not bother unless I am sure there's some significant performance impact, but I don't think there would be. \$\endgroup\$Alexander Pushkarev– Alexander Pushkarev2020年01月27日 10:25:53 +00:00Commented Jan 27, 2020 at 10:25
-
\$\begingroup\$ Ok, cool thanks I tried yesterday and didn’t find any significant benefit so switched back. \$\endgroup\$Ciasto piekarz– Ciasto piekarz2020年01月27日 10:27:06 +00:00Commented Jan 27, 2020 at 10:27
default