@@ -133,18 +133,28 @@ def connect(self, connection_string="mysql+pymysql://rcdb@127.0.0.1/rcdb", check
133133 self ._connection_string = connection_string
134134
135135 if check_version :
136- db_version = self .get_schema_version ()
137- if db_version != rcdb .SQL_SCHEMA_VERSION :
138- message = "SQL schema version doesn't match. " \
139- "Retrieved DB version is {0}, required version is {1}. " \
140- .format (db_version , rcdb .SQL_SCHEMA_VERSION )
141- if db_version is not None and db_version < rcdb .SQL_SCHEMA_VERSION :
142- message += "The database schema is older than this RCDB version. " \
143- "Run 'rcdb db update' to migrate the database to the current schema."
144- else :
145- message += "The database schema is newer than this RCDB version. " \
146- "Update your RCDB installation to match the database."
147- raise rcdb .errors .SqlSchemaVersionError (message )
136+ # This version query is the first statement that actually opens a
137+ # DB connection. If it fails (unreachable host, access denied, wrong
138+ # schema, ...) the engine/session we just built must be disposed
139+ # here: the exception propagates out of connect()/__init__, so the
140+ # caller never receives this provider to disconnect() it themselves,
141+ # and the engine's open connection would otherwise leak until GC.
142+ try :
143+ db_version = self .get_schema_version ()
144+ if db_version != rcdb .SQL_SCHEMA_VERSION :
145+ message = "SQL schema version doesn't match. " \
146+ "Retrieved DB version is {0}, required version is {1}. " \
147+ .format (db_version , rcdb .SQL_SCHEMA_VERSION )
148+ if db_version is not None and db_version < rcdb .SQL_SCHEMA_VERSION :
149+ message += "The database schema is older than this RCDB version. " \
150+ "Run 'rcdb db update' to migrate the database to the current schema."
151+ else :
152+ message += "The database schema is newer than this RCDB version. " \
153+ "Update your RCDB installation to match the database."
154+ raise rcdb .errors .SqlSchemaVersionError (message )
155+ except Exception :
156+ self .disconnect ()
157+ raise
148158
149159 # ------------------------------------------------
150160 # Closes connection to data
@@ -164,6 +174,11 @@ def disconnect(self):
164174 if self .engine is not None :
165175 self .engine .dispose ()
166176
177+ # ``close`` is an alias for ``disconnect``: a lot of calling code (and other
178+ # resource-holding objects) expects a ``close()`` method, while existing
179+ # RCDB code and users rely on the historical ``disconnect()`` name. Keep both.
180+ close = disconnect
181+
167182 # -------------------------------------------------
168183 # indicates ether the connection is open or not
169184 # -------------------------------------------------
0 commit comments