Connecting a Jupyter Notebook to a MySQL database seems like a straightforward task on the
surface. After all, it’s just a connection string, right? As I recently discovered, the path can be
fraught with unexpected errors, version incompatibilities, and a good dose of head-scratching.
This post chronicles my journey, the challenges I faced, my attempts to debug, and the ultimate
solution that finally got me connected.
My goal was to access a local MySQL database named united_nations from a Jupyter
Notebook using the %sql magic command. Based on common examples, my initial attempt
looked something like this:

I assumed this would work out of the box, specifying the database dialect (mysql), the driver
(pymysql), my credentials (root:Alister), host (localhost), port (3306), and the database name
(united_nations). I had ipython-sql and pymysql installed, so what could go wrong?
Frustrated by the persistent MySQLdb error, I reverted to my original, more explicit connection
string:
To my surprise, the error message changed. Now it said:
This was a classic “facepalm” moment. Despite my earlier confidence, this error unequivocally stated that pymysql itself was not found.
My Second Attempt & Rational: The solution was obvious: install pymysql! I ran:
Bash
!pip install pymysql
After confirming the installation, I re-ran the %load_ext sql and then my connection string. I was hopeful this time.
Alas, a new, more cryptic error emerged:
MetaData.__init__() got an unexpected keyword argument ‘bind’
Connection info needed in SQLAlchemy format, example:
postgresql://username:password@hostname/dbname
or an existing connection: dict_keys([])
This was completely new. “MetaData,” “init,” “bind” – these weren’t terms I directly used in my connection string. This error pointed to an internal issue within the libraries themselves.
My Third Attempt & Rational: A quick search revealed that MetaData.__init__() got an unexpected keyword argument ‘bind‘ is a well-known compatibility issue arising from SQLAlchemy 2.0 (or newer) breaking changes when used with older versions of ipython-sql. SQLAlchemy 2.0 removed the bind argument from MetaData‘s constructor, which ipython-sql was still attempting to use.
There were two paths forward:
The second option seemed cleaner and more future-proof. This led me to discover jupysql.
jupysql is a modern, better-maintained successor to ipython-sql, specifically designed to handle newer SQLAlchemy versions and provide a more robust experience.
Here’s the sequence of steps that finally brought success:
Uninstall the old ipython-sql:
Bash
!pip uninstall ipython-sql
Bash
!pip install jupysql
Bash
!pip install pymysql
Load the sql extension (now provided by jupysql):
Python
%load_ext sql
SQL
%sql mysql+pymysql://root:Alister@localhost:3306/united_nations
And with that, success! The connection was established without any errors, and I could finally start querying my database.
The journey highlights a common challenge in the Python ecosystem: managing package versions and understanding underlying dependencies.
What started as a simple task became an educational deep dive into Python package management and library compatibility. For anyone facing similar issues when connecting Jupyter Notebooks to MySQL, remember these key takeaways:
I hope this detailed account helps others avoid the same pitfalls and swiftly establish their database connections in Jupyter Notebooks. Happy querying!