Lab: Data Quality with Great Expectations

Hi all,
I got error with the below code, in the lab Data Quality with Great Expectations

mysql_datasource = context.sources.add_sql(
name=f"{LAB_PREFIX}-db-datasource", connection_string=“${MYSQL_CONNECTION_STRING}”
)

ConnectionRefusedError Traceback (most recent call last)
File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/pymysql/connections.py:644, in Connection.connect(self, sock)
643 try:
→ 644 sock = socket.create_connection(
645 (self.host, self.port), self.connect_timeout, **kwargs
646 )
647 break

File /usr/lib64/python3.9/socket.py:844, in create_connection(address, timeout, source_address)
843 try:
→ 844 raise err
845 finally:
846 # Break explicitly a reference cycle

File /usr/lib64/python3.9/socket.py:832, in create_connection(address, timeout, source_address)
831 sock.bind(source_address)
→ 832 sock.connect(sa)
833 # Break explicitly a reference cycle

ConnectionRefusedError: [Errno 111] Connection refused

During handling of the above exception, another exception occurred:

OperationalError Traceback (most recent call last)
File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/sqlalchemy/engine/base.py:145, in Connection.init(self, engine, connection, _has_events, _allow_revalidate, _allow_autobegin)
144 try:
→ 145 self._dbapi_connection = engine.raw_connection()
146 except dialect.loaded_dbapi.Error as err:

File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/sqlalchemy/engine/base.py:3293, in Engine.raw_connection(self)
3272 “”“Return a “raw” DBAPI connection from the connection pool.
3273
3274 The returned object is a proxied version of the DBAPI
(…)
3291
3292 “””
→ 3293 return self.pool.connect()

File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/sqlalchemy/pool/base.py:452, in Pool.connect(self)
445 “”“Return a DBAPI connection from the pool.
446
447 The connection is instrumented such that when its
(…)
450
451 “””
→ 452 return _ConnectionFairy._checkout(self)

File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/sqlalchemy/pool/base.py:1269, in _ConnectionFairy._checkout(cls, pool, threadconns, fairy)
1268 if not fairy:
→ 1269 fairy = _ConnectionRecord.checkout(pool)
1271 if threadconns is not None:

File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/sqlalchemy/pool/base.py:716, in _ConnectionRecord.checkout(cls, pool)
715 else:
→ 716 rec = pool._do_get()
718 try:

File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/sqlalchemy/pool/impl.py:170, in QueuePool._do_get(self)
169 with util.safe_reraise():
→ 170 self._dec_overflow()
171 raise

File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/sqlalchemy/util/langhelpers.py:146, in safe_reraise.exit(self, type_, value, traceback)
145 self._exc_info = None # remove potential circular references
→ 146 raise exc_value.with_traceback(exc_tb)
147 else:

File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/sqlalchemy/pool/impl.py:167, in QueuePool._do_get(self)
166 try:
→ 167 return self._create_connection()
168 except:

File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/sqlalchemy/pool/base.py:393, in Pool._create_connection(self)
391 “”“Called by subclasses to create a new ConnectionRecord.”“”
→ 393 return _ConnectionRecord(self)

File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/sqlalchemy/pool/base.py:678, in _ConnectionRecord.init(self, pool, connect)
677 if connect:
→ 678 self.__connect()
679 self.finalize_callback = deque()

File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/sqlalchemy/pool/base.py:903, in _ConnectionRecord.__connect(self)
902 with util.safe_reraise():
→ 903 pool.logger.debug(“Error on connect(): %s”, e)
904 else:
905 # in SQLAlchemy 1.4 the first_connect event is not used by
906 # the engine, so this will usually not be set

File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/sqlalchemy/util/langhelpers.py:146, in safe_reraise.exit(self, type_, value, traceback)
145 self._exc_info = None # remove potential circular references
→ 146 raise exc_value.with_traceback(exc_tb)
147 else:

File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/sqlalchemy/pool/base.py:898, in _ConnectionRecord.__connect(self)
897 self.starttime = time.time()
→ 898 self.dbapi_connection = connection = pool._invoke_creator(self)
899 pool.logger.debug(“Created new connection %r”, connection)

File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/sqlalchemy/engine/create.py:645, in create_engine..connect(connection_record)
643 return connection
→ 645 return dialect.connect(*cargs, **cparams)

File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/sqlalchemy/engine/default.py:616, in DefaultDialect.connect(self, *cargs, **cparams)
614 def connect(self, *cargs, **cparams):
615 # inherits the docstring from interfaces.Dialect.connect
→ 616 return self.loaded_dbapi.connect(*cargs, **cparams)

File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/pymysql/connections.py:358, in Connection.init(self, user, password, host, database, unix_socket, port, charset, collation, sql_mode, read_default_file, conv, use_unicode, client_flag, cursorclass, init_command, connect_timeout, read_default_group, autocommit, local_infile, max_allowed_packet, defer_connect, auth_plugin_map, read_timeout, write_timeout, bind_address, binary_prefix, program_name, server_public_key, ssl, ssl_ca, ssl_cert, ssl_disabled, ssl_key, ssl_verify_cert, ssl_verify_identity, compress, named_pipe, passwd, db)
357 else:
→ 358 self.connect()

File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/pymysql/connections.py:711, in Connection.connect(self, sock)
710 print(exc.traceback)
→ 711 raise exc
713 # If e is neither DatabaseError or IOError, It’s a bug.
714 # But raising AssertionError hides original error.
715 # So just reraise it.

OperationalError: (2003, “Can’t connect to MySQL server on ‘localhost’ ([Errno 111] Connection refused)”)

The above exception was the direct cause of the following exception:

OperationalError Traceback (most recent call last)
File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/great_expectations/datasource/fluent/sql_datasource.py:1143, in SQLDatasource.test_connection(self, test_assets)
1142 engine: sqlalchemy.Engine = self.get_engine()
→ 1143 engine.connect()
1144 except Exception as e:

File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/sqlalchemy/engine/base.py:3269, in Engine.connect(self)
3247 “”“Return a new :class:_engine.Connection object.
3248
3249 The :class:_engine.Connection acts as a Python context manager, so
(…)
3266
3267 “””
→ 3269 return self._connection_cls(self)

File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/sqlalchemy/engine/base.py:147, in Connection.init(self, engine, connection, _has_events, _allow_revalidate, _allow_autobegin)
146 except dialect.loaded_dbapi.Error as err:
→ 147 Connection._handle_dbapi_exception_noconnection(
148 err, dialect, engine
149 )
150 raise

File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/sqlalchemy/engine/base.py:2431, in Connection._handle_dbapi_exception_noconnection(cls, e, dialect, engine, is_disconnect, invalidate_pool_on_disconnect, is_pre_ping)
2430 assert sqlalchemy_exception is not None
→ 2431 raise sqlalchemy_exception.with_traceback(exc_info[2]) from e
2432 else:

File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/sqlalchemy/engine/base.py:145, in Connection.init(self, engine, connection, _has_events, _allow_revalidate, _allow_autobegin)
144 try:
→ 145 self._dbapi_connection = engine.raw_connection()
146 except dialect.loaded_dbapi.Error as err:

File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/sqlalchemy/engine/base.py:3293, in Engine.raw_connection(self)
3272 “”“Return a “raw” DBAPI connection from the connection pool.
3273
3274 The returned object is a proxied version of the DBAPI
(…)
3291
3292 “””
→ 3293 return self.pool.connect()

File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/sqlalchemy/pool/base.py:452, in Pool.connect(self)
445 “”“Return a DBAPI connection from the pool.
446
447 The connection is instrumented such that when its
(…)
450
451 “””
→ 452 return _ConnectionFairy._checkout(self)

File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/sqlalchemy/pool/base.py:1269, in _ConnectionFairy._checkout(cls, pool, threadconns, fairy)
1268 if not fairy:
→ 1269 fairy = _ConnectionRecord.checkout(pool)
1271 if threadconns is not None:

File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/sqlalchemy/pool/base.py:716, in _ConnectionRecord.checkout(cls, pool)
715 else:
→ 716 rec = pool._do_get()
718 try:

File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/sqlalchemy/pool/impl.py:170, in QueuePool._do_get(self)
169 with util.safe_reraise():
→ 170 self._dec_overflow()
171 raise

File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/sqlalchemy/util/langhelpers.py:146, in safe_reraise.exit(self, type_, value, traceback)
145 self._exc_info = None # remove potential circular references
→ 146 raise exc_value.with_traceback(exc_tb)
147 else:

File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/sqlalchemy/pool/impl.py:167, in QueuePool._do_get(self)
166 try:
→ 167 return self._create_connection()
168 except:

File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/sqlalchemy/pool/base.py:393, in Pool._create_connection(self)
391 “”“Called by subclasses to create a new ConnectionRecord.”“”
→ 393 return _ConnectionRecord(self)

File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/sqlalchemy/pool/base.py:678, in _ConnectionRecord.init(self, pool, connect)
677 if connect:
→ 678 self.__connect()
679 self.finalize_callback = deque()

File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/sqlalchemy/pool/base.py:903, in _ConnectionRecord.__connect(self)
902 with util.safe_reraise():
→ 903 pool.logger.debug(“Error on connect(): %s”, e)
904 else:
905 # in SQLAlchemy 1.4 the first_connect event is not used by
906 # the engine, so this will usually not be set

File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/sqlalchemy/util/langhelpers.py:146, in safe_reraise.exit(self, type_, value, traceback)
145 self._exc_info = None # remove potential circular references
→ 146 raise exc_value.with_traceback(exc_tb)
147 else:

File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/sqlalchemy/pool/base.py:898, in _ConnectionRecord.__connect(self)
897 self.starttime = time.time()
→ 898 self.dbapi_connection = connection = pool._invoke_creator(self)
899 pool.logger.debug(“Created new connection %r”, connection)

File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/sqlalchemy/engine/create.py:645, in create_engine..connect(connection_record)
643 return connection
→ 645 return dialect.connect(*cargs, **cparams)

File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/sqlalchemy/engine/default.py:616, in DefaultDialect.connect(self, *cargs, **cparams)
614 def connect(self, *cargs, **cparams):
615 # inherits the docstring from interfaces.Dialect.connect
→ 616 return self.loaded_dbapi.connect(*cargs, **cparams)

File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/pymysql/connections.py:358, in Connection.init(self, user, password, host, database, unix_socket, port, charset, collation, sql_mode, read_default_file, conv, use_unicode, client_flag, cursorclass, init_command, connect_timeout, read_default_group, autocommit, local_infile, max_allowed_packet, defer_connect, auth_plugin_map, read_timeout, write_timeout, bind_address, binary_prefix, program_name, server_public_key, ssl, ssl_ca, ssl_cert, ssl_disabled, ssl_key, ssl_verify_cert, ssl_verify_identity, compress, named_pipe, passwd, db)
357 else:
→ 358 self.connect()

File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/pymysql/connections.py:711, in Connection.connect(self, sock)
710 print(exc.traceback)
→ 711 raise exc
713 # If e is neither DatabaseError or IOError, It’s a bug.
714 # But raising AssertionError hides original error.
715 # So just reraise it.

OperationalError: (pymysql.err.OperationalError) (2003, “Can’t connect to MySQL server on ‘localhost’ ([Errno 111] Connection refused)”)
(Background on this error at: Error Messages — SQLAlchemy 2.0 Documentation)

The above exception was the direct cause of the following exception:

TestConnectionError Traceback (most recent call last)
Cell In[10], line 2
1 # Create the data source to represent the data available in the MySQL DB
----> 2 mysql_datasource = context.sources.add_sql(
3 name=f"{LAB_PREFIX}-db-datasource", connection_string=“${MYSQL_CONNECTION_STRING}”
4 )

File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/great_expectations/datasource/fluent/sources.py:472, in _SourceFactories.create_add_crud_method..add_datasource(name_or_datasource, **kwargs)
470 logger.debug(f"Adding {datasource_type} with {datasource.name}")
471 datasource._data_context = self._data_context
→ 472 datasource.test_connection()
473 datasource = self._data_context._add_fluent_datasource(datasource)
475 return datasource

File ~/environment/jupyterlab-venv/lib64/python3.9/site-packages/great_expectations/datasource/fluent/sql_datasource.py:1145, in SQLDatasource.test_connection(self, test_assets)
1143 engine.connect()
1144 except Exception as e:
→ 1145 raise TestConnectionError(
1146 “Attempt to connect to datasource failed with the following error message: "
1147 f”{e!s}"
1148 ) from e
1149 if self.assets and test_assets:
1150 for asset in self.assets:

TestConnectionError: Attempt to connect to datasource failed with the following error message: (pymysql.err.OperationalError) (2003, “Can’t connect to MySQL server on ‘localhost’ ([Errno 111] Connection refused)”)
(Background on this error at: Error Messages — SQLAlchemy 2.0 Documentation)

Hello @nhanvo
Looks like your notebook is looking in a wrong location (localhost) for the MySQL database. The variable MYSQL_CONNECTION_STRING is defined in the scripts/setup_jupyter_env.sh file, and it looks like this:
image
Somehow, the bashrc file on your cloud9 environment might have been changed after you ran source scripts/setup_jupyter_env.sh in step 6 of Vocareum instructions.
On your fresh retry, please run the command echo $MYSQL_CONNECTION_STRING in the Cloud9 environment, before running that cell, and share the results.