SQL¶
- class SqlService(internal_sql_service)[source]¶
Bases:
object
A service to execute SQL statements.
The service allows you to query data stored in a
Map
.Warning
The service is in beta state. Behavior and API might change in future releases.
Querying an IMap
Every Map instance is exposed as a table with the same name in the
partitioned
schema. Thepartitioned
schema is included into a default search path, therefore a Map could be referenced in an SQL statement with or without the schema name.Column resolution
Every table backed by a Map has a set of columns that are resolved automatically. Column resolution uses Map entries located on the member that initiates the query. The engine extracts columns from a key and a value and then merges them into a single column set. In case the key and the value have columns with the same name, the key takes precedence.
Columns are extracted from objects as follows (which happens on the server-side):
For non-Portable objects, public getters and fields are used to populate the column list. For getters, the first letter is converted to lower case. A getter takes precedence over a field in case of naming conflict.
For
Portable
objects, field names used in thewrite_portable()
method are used to populate the column list.
The whole key and value objects could be accessed through special fields
__key
andthis
, respectively. If key (value) object has fields, then the whole key (value) field is exposed as a normal field. Otherwise the field is hidden. Hidden fields can be accessed directly, but are not returned bySELECT * FROM ...
queries.Consider the following key/value model:
class PersonKey(Portable): def __init__(self, person_id=None, department_id=None): self.person_id = person_id self.department_id = department_id def write_portable(self, writer): writer.write_long("person_id", self.person_id) writer.write_long("department_id", self.department_id) ... class Person(Portable): def __init__(self, name=None): self.name = name def write_portable(self, writer): writer.write_string("name", self.name) ...
This model will be resolved to the following table columns:
person_id
BIGINT
department_id
BIGINT
name
VARCHAR
__key
OBJECT
(hidden)this
OBJECT
(hidden)
Consistency
Results returned from Map query are weakly consistent:
If an entry was not updated during iteration, it is guaranteed to be returned exactly once
If an entry was modified during iteration, it might be returned zero, one or several times
Usage
When a query is executed, an
SqlResult
is returned. You may get row iterator from the result. The result must be closed at the end. The iterator will close the result automatically when it is exhausted given that no error is raised during the iteration. The code snippet below demonstrates a typical usage pattern:client = hazelcast.HazelcastClient() result = client.sql.execute("SELECT * FROM person") for row in result: print(row.get_object("person_id")) print(row.get_object("name")) ...
See the documentation of the
SqlResult
for more information about different iteration methods.Notes
When an SQL statement is submitted to a member, it is parsed and optimized by the
hazelcast-sql
module. Thehazelcast-sql
must be in the classpath, otherwise an exception will be thrown. If you’re using thehazelcast-all
orhazelcast-enterprise-all
packages, thehazelcast-sql
module is included in them by default. If not, i.e., you are usinghazelcast
orhazelcast-enterprise
, then you need to havehazelcast-sql
in the classpath. If you are using the Docker image, the SQL module is included by default.- execute(sql, *params)[source]¶
Convenient method to execute a distributed query with the given parameters.
Converts passed SQL string and parameters into an
SqlStatement
object and invokesexecute_statement()
.- Parameters
sql (str) – SQL string.
*params – Query parameters that will be passed to
SqlStatement.add_parameter()
.
- Returns
The execution result.
- Return type
- Raises
HazelcastSqlError – In case of execution error.
AssertionError – If the SQL parameter is not a string.
ValueError – If the SQL parameter is an empty string.
- execute_statement(statement)[source]¶
Executes an SQL statement.
- Parameters
statement (SqlStatement) – Statement to be executed
- Returns
The execution result.
- Return type
- Raises
HazelcastSqlError – In case of execution error.
- class SqlColumnMetadata(name, column_type, nullable, is_nullable_exists)[source]¶
Bases:
object
Metadata of a column in an SQL row.
- property name¶
Name of the column.
- Type
str
- property type¶
Type of the column.
- Type
- property nullable¶
True
if this column values can beNone
,False
otherwise.- Type
bool
- class SqlColumnType[source]¶
Bases:
object
- VARCHAR = 0¶
Represented by
str
.
- BOOLEAN = 1¶
Represented by
bool
.
- TINYINT = 2¶
Represented by
int
.
- SMALLINT = 3¶
Represented by
int
.
- INTEGER = 4¶
Represented by
int
.
- BIGINT = 5¶
Represented by
int
(for Python 3) orlong
(for Python 2).
- DECIMAL = 6¶
Represented by
str
.
- REAL = 7¶
Represented by
float
.
- DOUBLE = 8¶
Represented by
float
.
- DATE = 9¶
Represented by
str
with theYYYY-MM-DD
format.
- TIME = 10¶
Represented by
str
with theHH:MM:SS[.ffffff]
format.
- TIMESTAMP = 11¶
Represented by
str
with theYYYY-MM-DDTHH:MM:SS[.ffffff]
format.
- TIMESTAMP_WITH_TIME_ZONE = 12¶
Represented by
str
with theYYYY-MM-DDTHH:MM:SS[.ffffff](+|-)HH:MM[:SS]
format.
- OBJECT = 13¶
Could be represented by any Python class.
- NULL = 14¶
The type of the generic SQL
NULL
literal.The only valid value of
NULL
type isNone
.
- exception HazelcastSqlError(originating_member_uuid, code, message, cause)[source]¶
Bases:
hazelcast.errors.HazelcastError
Represents an error occurred during the SQL query execution.
- property originating_member_uuid¶
UUID of the member that caused or initiated an error condition.
- Type
uuid.UUID
- class SqlRowMetadata(columns)[source]¶
Bases:
object
Metadata for the returned rows.
- COLUMN_NOT_FOUND = -1¶
Constant indicating that the column is not found.
- property columns¶
List of column metadata.
- Type
list[SqlColumnMetadata]
- property column_count¶
Number of columns in the row.
- Type
int
- get_column(index)[source]¶
- Parameters
index (int) – Zero-based column index.
- Returns
Metadata for the given column index.
- Return type
- Raises
IndexError – If the index is out of bounds.
AssertionError – If the index is not an integer.
- find_column(column_name)[source]¶
- Parameters
column_name (str) – Name of the column.
- Returns
Column index or
COLUMN_NOT_FOUND
if a column with the given name is not found.- Return type
int
- Raises
AssertionError – If the column name is not a string.
- class SqlRow(row_metadata, row)[source]¶
Bases:
object
One of the rows of an SQL query result.
- get_object(column_name)[source]¶
Gets the value in the column indicated by the column name.
Column name should be one of those defined in
SqlRowMetadata
, case-sensitive. You may also useSqlRowMetadata.find_column()
to test for column existence.The type of the returned value depends on the SQL type of the column. No implicit conversions are performed on the value.
- Parameters
column_name (str) –
- Returns
Value of the column.
- Raises
ValueError – If a column with the given name does not exist.
AssertionError – If the column name is not a string.
- get_object_with_index(column_index)[source]¶
Gets the value of the column by index.
The class of the returned value depends on the SQL type of the column. No implicit conversions are performed on the value.
- Parameters
column_index (int) – Zero-based column index.
- Returns
Value of the column.
- Raises
IndexError – If the column index is out of bounds.
AssertionError – If the column index is not an integer.
- property metadata¶
The row metadata.
- Type
- class SqlResult(sql_service, connection, query_id, cursor_buffer_size, execute_future)[source]¶
Bases:
object
SQL query result.
Depending on the statement type it represents a stream of rows or an update count.
To iterate over the stream of rows, there are two possible options.
The first, and the easiest one is to iterate over the rows in a blocking fashion.
result = client.sql.execute("SELECT ...") for row in result: # Process the row. print(row)
The second option is to use the non-blocking API with callbacks.
result = client.sql.execute("SELECT ...") it = result.iterator() # Future of iterator def on_iterator_response(iterator_future): iterator = iterator_future.result() def on_next_row(row_future): try: row = row_future.result() # Process the row. print(row) # Iterate over the next row. next(iterator).add_done_callback(on_next_row) except StopIteration: # Exhausted the iterator. No more rows are left. pass next(iterator).add_done_callback(on_next_row) it.add_done_callback(on_iterator_response)
When in doubt, use the blocking API shown in the first code sample.
Note that, iterators can be requested at most once per SqlResult.
One can call
close()
method of a result object to release the resources associated with the result on the server side. It might also be used to cancel query execution on the server side if it is still active.When the blocking API is used, one might also use
with
statement to automatically close the query even if an exception is thrown in the iteration.with client.sql.execute("SELECT ...") as result: for row in result: # Process the row. print(row)
To get the number of rows updated by the query, use the
update_count()
.update_count = client.sql.execute("SELECT ...").update_count().result()
One does not have to call
close()
in this case, because the result will already be closed in the server-side.- iterator()[source]¶
Returns the iterator over the result rows.
The iterator may be requested only once.
The returned Future results with:
HazelcastSqlError
: In case of an SQL execution error.ValueError: If the result only contains an update count, or the iterator is already requested.
- is_row_set()[source]¶
Returns whether this result has rows to iterate.
The returned Future results with:
HazelcastSqlError
: In case of an SQL execution error.
- Returns
- Return type
Future[bool]
- update_count()[source]¶
Returns the number of rows updated by the statement or
-1
if this result is a row set. In case the result doesn’t contain rows but the update count isn’t applicable or known,0
is returned.The returned Future results with:
HazelcastSqlError
: In case of an SQL execution error.
- Returns
- Return type
Future[int]
- get_row_metadata()[source]¶
Gets the row metadata.
The returned Future results with:
HazelcastSqlError
: In case of an SQL execution error.ValueError: If the result only contains an update count.
- Returns
- Return type
- close()[source]¶
Release the resources associated with the query result.
The query engine delivers the rows asynchronously. The query may become inactive even before all rows are consumed. The invocation of this command will cancel the execution of the query on all members if the query is still active. Otherwise it is no-op. For a result with an update count it is always no-op.
The returned Future results with:
HazelcastSqlError
: In case there is an error closing the result.
- Returns
- Return type
Future[None]
- class SqlExpectedResultType[source]¶
Bases:
object
The expected statement result type.
- ANY = 0¶
The statement may produce either rows or an update count.
- ROWS = 1¶
The statement must produce rows. An exception is thrown is the statement produces an update count.
- UPDATE_COUNT = 2¶
The statement must produce an update count. An exception is thrown is the statement produces rows.
- class SqlStatement(sql)[source]¶
Bases:
object
Definition of an SQL statement.
This object is mutable. Properties are read once before the execution is started. Changes to properties do not affect the behavior of already running statements.
- TIMEOUT_NOT_SET = -1¶
- TIMEOUT_DISABLED = 0¶
- DEFAULT_TIMEOUT = -1¶
- DEFAULT_CURSOR_BUFFER_SIZE = 4096¶
- property sql¶
The SQL string to be executed.
The setter raises:
AssertionError: If the SQL parameter is not a string.
ValueError: If the SQL parameter is an empty string.
- Type
str
- property schema¶
The schema name. The engine will try to resolve the non-qualified object identifiers from the statement in the given schema. If not found, the default search path will be used, which looks for objects in the predefined schemas
partitioned
andpublic
.The schema name is case sensitive. For example,
foo
andFoo
are different schemas.The default value is
None
meaning only the default search path is used.The setter raises:
AssertionError: If the schema is not a string or
None
.
- Type
str
- property parameters¶
Sets the statement parameters.
You may define parameter placeholders in the statement with the
?
character. For every placeholder, a parameter value must be provided.When the setter is called, the content of the parameters list is copied. Subsequent changes to the original list don’t change the statement parameters.
The setter raises:
AssertionError: If the parameter is not a list.
- Type
list
- property timeout¶
The execution timeout in seconds.
If the timeout is reached for a running statement, it will be cancelled forcefully.
Zero value means no timeout.
TIMEOUT_NOT_SET
means that the value from the server-side config will be used. Other negative values are prohibited.Defaults to
TIMEOUT_NOT_SET
.The setter raises:
AssertionError: If the timeout is not an integer or float.
ValueError: If the timeout is negative and not equal to
TIMEOUT_NOT_SET
.
- Type
float or int
- property cursor_buffer_size¶
The cursor buffer size (measured in the number of rows).
When a statement is submitted for execution, a
SqlResult
is returned as a result. When rows are ready to be consumed, they are put into an internal buffer of the cursor. This parameter defines the maximum number of rows in that buffer. When the threshold is reached, the backpressure mechanism will slow down the execution, possibly to a complete halt, to prevent out-of-memory.Only positive values are allowed.
The default value is expected to work well for most workloads. A bigger buffer size may give you a slight performance boost for queries with large result sets at the cost of increased memory consumption.
Defaults to
DEFAULT_CURSOR_BUFFER_SIZE
.The setter raises:
AssertionError: If the cursor buffer size is not an integer.
ValueError: If the cursor buffer size is not positive.
- Type
int
- property expected_result_type¶
The expected result type.
The setter raises:
TypeError: If the expected result type does not equal to one of the values or names of the members of the
SqlExpectedResultType
.
- add_parameter(parameter)[source]¶
Adds a single parameter to the end of the parameters list.
- Parameters
parameter – The parameter.