diff --git a/docs/by-example/http.rst b/docs/by-example/http.rst index 2b855637e..6bda6303c 100644 --- a/docs/by-example/http.rst +++ b/docs/by-example/http.rst @@ -23,10 +23,12 @@ Server configuration A list of servers can be passed while creating an instance of the http client:: >>> http_client = HttpClient([crate_host]) + >>> http_client.close() Its also possible to pass a single server as a string:: >>> http_client = HttpClient(crate_host) + >>> http_client.close() If no ``server`` argument (or no argument at all) is passed, the default one ``127.0.0.1:4200`` is used:: @@ -34,6 +36,7 @@ If no ``server`` argument (or no argument at all) is passed, the default one >>> http_client = HttpClient() >>> http_client._active_servers ['http://127.0.0.1:4200'] + >>> http_client.close() When using a list of servers, the servers are selected by round-robin:: @@ -49,6 +52,8 @@ When using a list of servers, the servers are selected by round-robin:: >>> http_client._get_server() 'http://even_more_invalid_host:9999' + >>> http_client.close() + Servers with connection errors will be removed from the active server list:: >>> http_client = HttpClient([invalid_host, even_more_invalid_host, crate_host]) @@ -66,6 +71,7 @@ To validate this, set the interval very short and sleep for that interval:: ['http://invalid_host:9999', 'http://even_more_invalid_host:9999', 'http://127.0.0.1:44209'] + >>> http_client.close() If no active servers are available and the retry interval is not reached, just use the oldest inactive one:: @@ -75,6 +81,7 @@ inactive one:: >>> http_client._active_servers = [] >>> http_client._get_server() 'http://invalid_host:9999' + >>> http_client.close() SQL Statements ============== @@ -117,8 +124,7 @@ Trying to get a non-existing blob throws an exception:: ... crate.client.exceptions.DigestNotFoundException: myfiles/041f06fd774092478d450774f5ba30c5da78acc8 -Creating a new blob - this method returns True if the blob was newly -created, false if it already exists:: +Creating a new blob - this method returns True if the blob was newly created:: >>> from tempfile import TemporaryFile >>> f = TemporaryFile() @@ -128,6 +134,8 @@ created, false if it already exists:: ... 'myfiles', '040f06fd774092478d450774f5ba30c5da78acc8', f) True +Uploading the same content again returns ``False``:: + >>> _ = f.seek(0) >>> http_client.blob_put( ... 'myfiles', '040f06fd774092478d450774f5ba30c5da78acc8', f) @@ -171,6 +179,10 @@ Uploading a blob to a table with disabled blob support throws an exception:: ... crate.client.exceptions.BlobLocationNotFoundException: locations/040f06fd774092478d450774f5ba30c5da78acc8 + >>> http_client.close() + >>> f.close() + + Error Handling ============== @@ -185,6 +197,7 @@ timeout exception:: ... ' ... ''') {...} + >>> http_client.close() It's possible to define a HTTP timeout in seconds on client instantiation, so an exception is raised when the timeout is reached:: @@ -194,6 +207,7 @@ an exception is raised when the timeout is reached:: Traceback (most recent call last): ... crate.client.exceptions.ConnectionError: No more Servers available, exception from last server: ... + >>> http_client.close() When connecting to non-CrateDB servers, the HttpClient will raise a ConnectionError like this:: @@ -203,6 +217,7 @@ When connecting to non-CrateDB servers, the HttpClient will raise a ConnectionEr ... crate.client.exceptions.ProgrammingError: Invalid server response of content-type 'text/html; charset=utf-8': ... + >>> http_client.close() When using the ``error_trace`` kwarg a full traceback of the server exception will be provided:: @@ -217,3 +232,4 @@ will be provided:: >>> print(trace) TRACE: ... mismatched input 'error' expecting {, ... at io.crate... + >>> http_client.close() diff --git a/docs/by-example/sqlalchemy/cru.rst b/docs/by-example/sqlalchemy/cru.rst index 285bb74e8..78db8f9e3 100644 --- a/docs/by-example/sqlalchemy/cru.rst +++ b/docs/by-example/sqlalchemy/cru.rst @@ -279,6 +279,9 @@ Refresh "characters" table: >>> pprint(char.details) {'name': {'first': 'Trillian', 'last': 'Dent'}, 'size': 45} -.. Hidden: close connection +.. hidden: Disconnect from database + + >>> session.close() >>> connection.close() + >>> engine.dispose() diff --git a/docs/by-example/sqlalchemy/getting-started.rst b/docs/by-example/sqlalchemy/getting-started.rst index 52b3f4f9c..d8c20776c 100644 --- a/docs/by-example/sqlalchemy/getting-started.rst +++ b/docs/by-example/sqlalchemy/getting-started.rst @@ -380,22 +380,23 @@ First the table definition as class: As seen below the table doesn't exist yet: - >>> conn = engine.connect() - >>> engine.dialect.has_table(conn, table_name='departments') + >>> engine.dialect.has_table(connection, table_name='departments') False -In order to create all missing tables the ``create_all`` method can be used: +In order to create all missing tables, the ``create_all`` method can be used: >>> Base.metadata.create_all(bind=engine) - >>> engine.dialect.has_table(conn, table_name='departments') +With that, the table has been created: + + >>> engine.dialect.has_table(connection, table_name='departments') True >>> stmt = ("select table_name, column_name, ordinal_position, data_type " ... "from information_schema.columns " ... "where table_name = 'departments' " ... "order by column_name") - >>> pprint([str(r) for r in conn.execute(stmt)]) + >>> pprint([str(r) for r in connection.execute(stmt)]) ["('departments', 'code', 3, 'integer')", "('departments', 'id', 1, 'text')", "('departments', 'name', 2, 'text')"] @@ -408,7 +409,7 @@ delete a single table use ``drop(...)`` as shown below: >>> Base.metadata.tables['departments'].drop(engine) - >>> engine.dialect.has_table(conn, table_name='departments') + >>> engine.dialect.has_table(connection, table_name='departments') False Insert From Select @@ -466,5 +467,10 @@ This will result in the following query: >>> pprint([str(r) for r in session.execute("Select content from archived_tasks")]) ["('Write Tests',)"] +.. hidden: Disconnect from database + + >>> session.close() + >>> connection.close() + >>> engine.dispose() .. _count result rows: http://docs.sqlalchemy.org/en/14/orm/tutorial.html#counting diff --git a/docs/by-example/sqlalchemy/inspection-reflection.rst b/docs/by-example/sqlalchemy/inspection-reflection.rst index 140813ca5..7c50987f2 100644 --- a/docs/by-example/sqlalchemy/inspection-reflection.rst +++ b/docs/by-example/sqlalchemy/inspection-reflection.rst @@ -109,7 +109,7 @@ Check if table exists: True -.. Hidden: close connection +.. hidden: Disconnect from database >>> connection.close() >>> engine.dispose() diff --git a/src/crate/client/tests.py b/src/crate/client/tests.py index 3aa1a13dd..4e8bdcb3e 100644 --- a/src/crate/client/tests.py +++ b/src/crate/client/tests.py @@ -135,6 +135,8 @@ def setUpWithCrateLayer(test): cursor.execute("CREATE USER me WITH (password = 'my_secret_pw')") cursor.execute("CREATE USER trusted_me") + cursor.close() + def setUpCrateLayerAndSqlAlchemy(test): setUpWithCrateLayer(test) @@ -166,6 +168,7 @@ def setUpCrateLayerAndSqlAlchemy(test): engine = sa.create_engine(f"crate://{crate_host}") for ddl_statement in ddl_statements: engine.execute(sa.text(ddl_statement)) + engine.dispose() class HttpsTestServerLayer: @@ -280,6 +283,7 @@ def _try_execute(cursor, stmt): def tearDownWithCrateLayer(test): # clear testing data with connect(crate_host) as conn: + cursor = conn.cursor() for stmt in ["DROP TABLE locations", "DROP BLOB TABLE myfiles", "DROP TABLE characters", @@ -288,7 +292,7 @@ def tearDownWithCrateLayer(test): "DROP USER me", "DROP USER trusted_me", ]: - _try_execute(conn.cursor(), stmt) + _try_execute(cursor, stmt) def test_suite():