I have a package that allows the user to use any one of 4 packages they want to connect to a database. It works great but I'm unhappy with the way I'm importing things.
I could simply import all the packages, but I don't want to do that in case the specific user doesn't ever need to use turbodbc
for example:
import pyodbc
import pymssql
import turbodbc
from ibmdbpy.base import IdaDataBase
Currently, I have the following situation. I try to import all of them, but the ones that don't import, no problem, My program simply assumes they will not be called and if they are it errors:
# some envs may not have all these packages installed so we try each:
try:
import pyodbc
except:
pass
try:
import pymssql
except:
pass
try:
import turbodbc
except:
pass
try:
from ibmdbpy.base import IdaDataBase
except:
pass
This doesn't feel pythonic. So I know there are packages such as holoviews or tensorflow that allow you to specify a backend. They are of course orders of magnitude more complicated than mine, but they have to handle the same pattern.
How can I make this code right? it is technically buggy because if they intend to use pyodbc
but don't have it installed, my program will not warn them, it will error at runtime. So really this goes beyond esthetics or philosophy; this is technically error-prone code.
How would you handle this situation?
Fyi, here is an example of how the code is called:
connect('Playground', package='pymssql')
try:
import pyodbc
except ImportError:
pyodbc = None
then later:
if pyodbc is None and user_wants_to_use_pyodbc:
print_warning()
raise SomeConfigurationErrorOrSuch()
This approach works well for a small number of options. If you have enough options that you need to abstract out this approach, then you can use the importlib
module to import modules under the control of your program.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With