flowserv.model.base module
Define the classes in the Object-Relational Mapping.
- class flowserv.model.base.APIKey(**kwargs)
Bases:
sqlalchemy.orm.decl_api.BaseAPI key assigned to a user at login.
- expires
- user_id
- value
- class flowserv.model.base.FileObject(**kwargs)
Bases:
sqlalchemy.orm.decl_api.BaseThe file handle base class provides additional methods to access a file and its properties.
- created_at = Column(None, String(length=32), table=None, nullable=False, default=ColumnDefault(<function utc_now>))
- file_id = Column(None, String(length=32), table=None, primary_key=True, nullable=False, default=ColumnDefault(<function get_unique_identifier>))
- key = Column(None, String(length=1024), table=None, nullable=False)
- mime_type = Column(None, String(length=64), table=None)
- name = Column(None, String(length=512), table=None, nullable=False)
- size = Column(None, Integer(), table=None, nullable=False)
- class flowserv.model.base.GroupObject(**kwargs)
Bases:
sqlalchemy.orm.decl_api.BaseA workflow group associates a set of users with a workflow template. It allows to define a group-specific set of parameters for the template.
- engine_config
- group_id
- members
- name
- owner
- owner_id
- parameters
- runs
- uploads
- workflow
- workflow_id
- workflow_spec
- class flowserv.model.base.JsonObject(*args, **kwargs)
Bases:
sqlalchemy.sql.type_api.TypeDecoratorDecorator for objects that are stored as serialized JSON strings.
- cache_ok = True
Indicate if statements using this
ExternalTypeare “safe to cache”.The default value
Nonewill emit a warning and then not allow caching of a statement which includes this type. Set toFalseto disable statements using this type from being cached at all without a warning. When set toTrue, the object’s class and selected elements from its state will be used as part of the cache key. For example, using aTypeDecorator:class MyType(TypeDecorator): impl = String cache_ok = True def __init__(self, choices): self.choices = tuple(choices) self.internal_only = True
The cache key for the above type would be equivalent to:
>>> MyType(["a", "b", "c"])._static_cache_key (<class '__main__.MyType'>, ('choices', ('a', 'b', 'c')))
The caching scheme will extract attributes from the type that correspond to the names of parameters in the
__init__()method. Above, the “choices” attribute becomes part of the cache key but “internal_only” does not, because there is no parameter named “internal_only”.The requirements for cacheable elements is that they are hashable and also that they indicate the same SQL rendered for expressions using this type every time for a given cache value.
To accommodate for datatypes that refer to unhashable structures such as dictionaries, sets and lists, these objects can be made “cacheable” by assigning hashable structures to the attributes whose names correspond with the names of the arguments. For example, a datatype which accepts a dictionary of lookup values may publish this as a sorted series of tuples. Given a previously un-cacheable type as:
class LookupType(UserDefinedType): '''a custom type that accepts a dictionary as a parameter. this is the non-cacheable version, as "self.lookup" is not hashable. ''' def __init__(self, lookup): self.lookup = lookup def get_col_spec(self, **kw): return "VARCHAR(255)" def bind_processor(self, dialect): # ... works with "self.lookup" ...
Where “lookup” is a dictionary. The type will not be able to generate a cache key:
>>> type_ = LookupType({"a": 10, "b": 20}) >>> type_._static_cache_key <stdin>:1: SAWarning: UserDefinedType LookupType({'a': 10, 'b': 20}) will not produce a cache key because the ``cache_ok`` flag is not set to True. Set this flag to True if this type object's state is safe to use in a cache key, or False to disable this warning. symbol('no_cache')
If we did set up such a cache key, it wouldn’t be usable. We would get a tuple structure that contains a dictionary inside of it, which cannot itself be used as a key in a “cache dictionary” such as SQLAlchemy’s statement cache, since Python dictionaries aren’t hashable:
>>> # set cache_ok = True >>> type_.cache_ok = True >>> # this is the cache key it would generate >>> key = type_._static_cache_key >>> key (<class '__main__.LookupType'>, ('lookup', {'a': 10, 'b': 20})) >>> # however this key is not hashable, will fail when used with >>> # SQLAlchemy statement cache >>> some_cache = {key: "some sql value"} Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unhashable type: 'dict'
The type may be made cacheable by assigning a sorted tuple of tuples to the “.lookup” attribute:
class LookupType(UserDefinedType): '''a custom type that accepts a dictionary as a parameter. The dictionary is stored both as itself in a private variable, and published in a public variable as a sorted tuple of tuples, which is hashable and will also return the same value for any two equivalent dictionaries. Note it assumes the keys and values of the dictionary are themselves hashable. ''' cache_ok = True def __init__(self, lookup): self._lookup = lookup # assume keys/values of "lookup" are hashable; otherwise # they would also need to be converted in some way here self.lookup = tuple( (key, lookup[key]) for key in sorted(lookup) ) def get_col_spec(self, **kw): return "VARCHAR(255)" def bind_processor(self, dialect): # ... works with "self._lookup" ...
Where above, the cache key for
LookupType({"a": 10, "b": 20})will be:>>> LookupType({"a": 10, "b": 20})._static_cache_key (<class '__main__.LookupType'>, ('lookup', (('a', 10), ('b', 20))))
New in version 1.4.14: - added the
cache_okflag to allow some configurability of caching forTypeDecoratorclasses.New in version 1.4.28: - added the
ExternalTypemixin which generalizes thecache_okflag to both theTypeDecoratorandUserDefinedTypeclasses.See also
sql_caching
- impl
alias of
sqlalchemy.sql.sqltypes.Unicode
- process_bind_param(value, dialect)
Expects a JSON serializable object.
- process_literal_param(value, dialect)
Expects a JSON serializable object.
- process_result_value(value, dialect)
Create JSON object from string serialization.
- class flowserv.model.base.PasswordRequest(**kwargs)
Bases:
sqlalchemy.orm.decl_api.BaseUnique identifier associated with a password reset request.
- expires
- request_id
- user_id
- class flowserv.model.base.RunFile(**kwargs)
Bases:
flowserv.model.base.FileObjectFile resources that are created by successful workflow runs.
- created_at
- file_id
- key
- mime_type
- name
- run
- run_id
- size
- class flowserv.model.base.RunMessage(**kwargs)
Bases:
sqlalchemy.orm.decl_api.BaseLog for messages created by workflow runs. Primarily used for error messages by now.
- message
- pos
- run
- run_id
- class flowserv.model.base.RunObject(**kwargs)
Bases:
sqlalchemy.orm.decl_api.BaseWorkflow runs may be triggered by workflow group members or they represent post-processing workflows. In the latter case the group identifier is None.
- arguments
- created_at
- ended_at
- files
- get_file(by_id=None, by_key=None)
Get handle for identified file. A file can either be identified by the unique identifier or file key (i.e., relative path name). Returns None if the file is not found.
Raises a ValueError if an invalid combination of parameters is given.
- Parameters
by_id (string) – Unique file identifier.
by_key (string) – Relative path to the file in the run directory.
- Return type
- group
- group_id
- is_active()
A run is in active state if it is either pending or running.
- Return type
bool
- is_canceled()
Returns True if the run state is of type CANCELED.
- Return type
bool
- is_error()
Returns True if the run state is of type ERROR.
- Return type
bool
- is_pending()
Returns True if the run state is of type PENDING.
- Return type
bool
- is_running()
Returns True if the run state is of type RUNNING.
- Return type
bool
- is_success()
Returns True if the run state is of type SUCCESS.
- Return type
bool
- log
- outputs()
Get specification of output file properties. The result is a dictionary of workflow output file specifications keyed by either the user-specified key or the file source. If the workflow template does not contain any output file specifications the result is an empty dictionary.
If the run is associated with a group, then the output file specification of the associated workflow is returned. If the run is a post-processing run the optional output specification in the post- processing workflow template is returned.
- Returns
dict(string
- Return type
- result
- run_id
- started_at
- state()
Get an instance of the workflow state for the given run.
- Return type
- state_type
- workflow
- workflow_id
- class flowserv.model.base.UploadFile(**kwargs)
Bases:
flowserv.model.base.FileObjectUploaded files are assigned to individual workflow groups. Each file is assigned a unique identifier.
- created_at
- file_id
- group
- group_id
- key
- mime_type
- name
- size
- class flowserv.model.base.User(**kwargs)
Bases:
sqlalchemy.orm.decl_api.BaseEach user that registers with the application has a unique identifier and a unique user name associated with them.
For users that are logged into the system the user handle contains the API key that was assigned during login..
- active
- api_key
- groups
- is_logged_in()
Test if the user API key is set as an indicator of whether the user is currently logged in or not.
- Return type
bool
- name
- password_request
- secret
- user_id
- class flowserv.model.base.WorkflowObject(**kwargs)
Bases:
sqlalchemy.orm.decl_api.BaseEach workflow has a unique name, an optional short descriptor and long instruction text. The five main components of the template are (i) the workflow specification, (ii) the list of parameter declarations, (iii) an optional post-processing workflow specification, (iv) the optional grouping of parameters into sets, and (v) the result schema for workflows that generate metrics for individual workflow runs.
With each workflow a reference to the latest run containing post-processing results is maintained. The value is NULL if no post-porcessing workflow is defined for the template or if it has not been executed yet. The post- processing key contains the sorted list of identifier for the runs that were used as input to generate the post-processing results.
- description
- engine_config
- get_template(workflow_spec=None, parameters=None)
Get template for the workflow. The optional parameters allow to override the default values with group-specific values.
- Parameters
workflow_spec (dict, default=None) – Modified workflow specification.
parameters (dict(flowserv.model.parameter.base.Parameter)) – Modified wokflow parameter list.
- Return type
- groups
- ignore_postproc
- instructions
- name
- outputs
- parameter_groups
- parameters
- postproc_ranking
- postproc_run_id
- postproc_spec
- ranking()
Get list of identifier for runs in the current ranking sorted by their rank.
- Return type
list(string)
- result_schema
- property run_postproc
Returns True iff the result schema and post-processing workflow are defined and the ignore_postproc flag is False.
- Return type
bool
- runs
- workflow_id
- workflow_spec
- class flowserv.model.base.WorkflowOutputs(*args, **kwargs)
Bases:
sqlalchemy.sql.type_api.TypeDecoratorDecorator for workflow output file specifications that are stored as serialized Json objects.
- cache_ok = True
Indicate if statements using this
ExternalTypeare “safe to cache”.The default value
Nonewill emit a warning and then not allow caching of a statement which includes this type. Set toFalseto disable statements using this type from being cached at all without a warning. When set toTrue, the object’s class and selected elements from its state will be used as part of the cache key. For example, using aTypeDecorator:class MyType(TypeDecorator): impl = String cache_ok = True def __init__(self, choices): self.choices = tuple(choices) self.internal_only = True
The cache key for the above type would be equivalent to:
>>> MyType(["a", "b", "c"])._static_cache_key (<class '__main__.MyType'>, ('choices', ('a', 'b', 'c')))
The caching scheme will extract attributes from the type that correspond to the names of parameters in the
__init__()method. Above, the “choices” attribute becomes part of the cache key but “internal_only” does not, because there is no parameter named “internal_only”.The requirements for cacheable elements is that they are hashable and also that they indicate the same SQL rendered for expressions using this type every time for a given cache value.
To accommodate for datatypes that refer to unhashable structures such as dictionaries, sets and lists, these objects can be made “cacheable” by assigning hashable structures to the attributes whose names correspond with the names of the arguments. For example, a datatype which accepts a dictionary of lookup values may publish this as a sorted series of tuples. Given a previously un-cacheable type as:
class LookupType(UserDefinedType): '''a custom type that accepts a dictionary as a parameter. this is the non-cacheable version, as "self.lookup" is not hashable. ''' def __init__(self, lookup): self.lookup = lookup def get_col_spec(self, **kw): return "VARCHAR(255)" def bind_processor(self, dialect): # ... works with "self.lookup" ...
Where “lookup” is a dictionary. The type will not be able to generate a cache key:
>>> type_ = LookupType({"a": 10, "b": 20}) >>> type_._static_cache_key <stdin>:1: SAWarning: UserDefinedType LookupType({'a': 10, 'b': 20}) will not produce a cache key because the ``cache_ok`` flag is not set to True. Set this flag to True if this type object's state is safe to use in a cache key, or False to disable this warning. symbol('no_cache')
If we did set up such a cache key, it wouldn’t be usable. We would get a tuple structure that contains a dictionary inside of it, which cannot itself be used as a key in a “cache dictionary” such as SQLAlchemy’s statement cache, since Python dictionaries aren’t hashable:
>>> # set cache_ok = True >>> type_.cache_ok = True >>> # this is the cache key it would generate >>> key = type_._static_cache_key >>> key (<class '__main__.LookupType'>, ('lookup', {'a': 10, 'b': 20})) >>> # however this key is not hashable, will fail when used with >>> # SQLAlchemy statement cache >>> some_cache = {key: "some sql value"} Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unhashable type: 'dict'
The type may be made cacheable by assigning a sorted tuple of tuples to the “.lookup” attribute:
class LookupType(UserDefinedType): '''a custom type that accepts a dictionary as a parameter. The dictionary is stored both as itself in a private variable, and published in a public variable as a sorted tuple of tuples, which is hashable and will also return the same value for any two equivalent dictionaries. Note it assumes the keys and values of the dictionary are themselves hashable. ''' cache_ok = True def __init__(self, lookup): self._lookup = lookup # assume keys/values of "lookup" are hashable; otherwise # they would also need to be converted in some way here self.lookup = tuple( (key, lookup[key]) for key in sorted(lookup) ) def get_col_spec(self, **kw): return "VARCHAR(255)" def bind_processor(self, dialect): # ... works with "self._lookup" ...
Where above, the cache key for
LookupType({"a": 10, "b": 20})will be:>>> LookupType({"a": 10, "b": 20})._static_cache_key (<class '__main__.LookupType'>, ('lookup', (('a', 10), ('b', 20))))
New in version 1.4.14: - added the
cache_okflag to allow some configurability of caching forTypeDecoratorclasses.New in version 1.4.28: - added the
ExternalTypemixin which generalizes thecache_okflag to both theTypeDecoratorandUserDefinedTypeclasses.See also
sql_caching
- impl
alias of
sqlalchemy.sql.sqltypes.Unicode
- process_bind_param(value, dialect)
Expects a list of workflow output file objects.
- process_literal_param(value, dialect)
Expects a list of workflow output file objects.
- process_result_value(value, dialect)
Create workflow output file list from JSON serialization.
- class flowserv.model.base.WorkflowParameterGroups(*args, **kwargs)
Bases:
sqlalchemy.sql.type_api.TypeDecoratorDecorator for workflow parameters groups that are stored as serialized Json objects.
- cache_ok = True
Indicate if statements using this
ExternalTypeare “safe to cache”.The default value
Nonewill emit a warning and then not allow caching of a statement which includes this type. Set toFalseto disable statements using this type from being cached at all without a warning. When set toTrue, the object’s class and selected elements from its state will be used as part of the cache key. For example, using aTypeDecorator:class MyType(TypeDecorator): impl = String cache_ok = True def __init__(self, choices): self.choices = tuple(choices) self.internal_only = True
The cache key for the above type would be equivalent to:
>>> MyType(["a", "b", "c"])._static_cache_key (<class '__main__.MyType'>, ('choices', ('a', 'b', 'c')))
The caching scheme will extract attributes from the type that correspond to the names of parameters in the
__init__()method. Above, the “choices” attribute becomes part of the cache key but “internal_only” does not, because there is no parameter named “internal_only”.The requirements for cacheable elements is that they are hashable and also that they indicate the same SQL rendered for expressions using this type every time for a given cache value.
To accommodate for datatypes that refer to unhashable structures such as dictionaries, sets and lists, these objects can be made “cacheable” by assigning hashable structures to the attributes whose names correspond with the names of the arguments. For example, a datatype which accepts a dictionary of lookup values may publish this as a sorted series of tuples. Given a previously un-cacheable type as:
class LookupType(UserDefinedType): '''a custom type that accepts a dictionary as a parameter. this is the non-cacheable version, as "self.lookup" is not hashable. ''' def __init__(self, lookup): self.lookup = lookup def get_col_spec(self, **kw): return "VARCHAR(255)" def bind_processor(self, dialect): # ... works with "self.lookup" ...
Where “lookup” is a dictionary. The type will not be able to generate a cache key:
>>> type_ = LookupType({"a": 10, "b": 20}) >>> type_._static_cache_key <stdin>:1: SAWarning: UserDefinedType LookupType({'a': 10, 'b': 20}) will not produce a cache key because the ``cache_ok`` flag is not set to True. Set this flag to True if this type object's state is safe to use in a cache key, or False to disable this warning. symbol('no_cache')
If we did set up such a cache key, it wouldn’t be usable. We would get a tuple structure that contains a dictionary inside of it, which cannot itself be used as a key in a “cache dictionary” such as SQLAlchemy’s statement cache, since Python dictionaries aren’t hashable:
>>> # set cache_ok = True >>> type_.cache_ok = True >>> # this is the cache key it would generate >>> key = type_._static_cache_key >>> key (<class '__main__.LookupType'>, ('lookup', {'a': 10, 'b': 20})) >>> # however this key is not hashable, will fail when used with >>> # SQLAlchemy statement cache >>> some_cache = {key: "some sql value"} Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unhashable type: 'dict'
The type may be made cacheable by assigning a sorted tuple of tuples to the “.lookup” attribute:
class LookupType(UserDefinedType): '''a custom type that accepts a dictionary as a parameter. The dictionary is stored both as itself in a private variable, and published in a public variable as a sorted tuple of tuples, which is hashable and will also return the same value for any two equivalent dictionaries. Note it assumes the keys and values of the dictionary are themselves hashable. ''' cache_ok = True def __init__(self, lookup): self._lookup = lookup # assume keys/values of "lookup" are hashable; otherwise # they would also need to be converted in some way here self.lookup = tuple( (key, lookup[key]) for key in sorted(lookup) ) def get_col_spec(self, **kw): return "VARCHAR(255)" def bind_processor(self, dialect): # ... works with "self._lookup" ...
Where above, the cache key for
LookupType({"a": 10, "b": 20})will be:>>> LookupType({"a": 10, "b": 20})._static_cache_key (<class '__main__.LookupType'>, ('lookup', (('a', 10), ('b', 20))))
New in version 1.4.14: - added the
cache_okflag to allow some configurability of caching forTypeDecoratorclasses.New in version 1.4.28: - added the
ExternalTypemixin which generalizes thecache_okflag to both theTypeDecoratorandUserDefinedTypeclasses.See also
sql_caching
- impl
alias of
sqlalchemy.sql.sqltypes.Unicode
- process_bind_param(value, dialect)
Expects a list of workflow module objects.
- process_literal_param(value, dialect)
Expects a list of workflow module objects.
- process_result_value(value, dialect)
Create workflow module list from JSON serialization.
- class flowserv.model.base.WorkflowParameters(*args, **kwargs)
Bases:
sqlalchemy.sql.type_api.TypeDecoratorDecorator for workflow parameters that are stored as serialized Json objects.
- cache_ok = True
Indicate if statements using this
ExternalTypeare “safe to cache”.The default value
Nonewill emit a warning and then not allow caching of a statement which includes this type. Set toFalseto disable statements using this type from being cached at all without a warning. When set toTrue, the object’s class and selected elements from its state will be used as part of the cache key. For example, using aTypeDecorator:class MyType(TypeDecorator): impl = String cache_ok = True def __init__(self, choices): self.choices = tuple(choices) self.internal_only = True
The cache key for the above type would be equivalent to:
>>> MyType(["a", "b", "c"])._static_cache_key (<class '__main__.MyType'>, ('choices', ('a', 'b', 'c')))
The caching scheme will extract attributes from the type that correspond to the names of parameters in the
__init__()method. Above, the “choices” attribute becomes part of the cache key but “internal_only” does not, because there is no parameter named “internal_only”.The requirements for cacheable elements is that they are hashable and also that they indicate the same SQL rendered for expressions using this type every time for a given cache value.
To accommodate for datatypes that refer to unhashable structures such as dictionaries, sets and lists, these objects can be made “cacheable” by assigning hashable structures to the attributes whose names correspond with the names of the arguments. For example, a datatype which accepts a dictionary of lookup values may publish this as a sorted series of tuples. Given a previously un-cacheable type as:
class LookupType(UserDefinedType): '''a custom type that accepts a dictionary as a parameter. this is the non-cacheable version, as "self.lookup" is not hashable. ''' def __init__(self, lookup): self.lookup = lookup def get_col_spec(self, **kw): return "VARCHAR(255)" def bind_processor(self, dialect): # ... works with "self.lookup" ...
Where “lookup” is a dictionary. The type will not be able to generate a cache key:
>>> type_ = LookupType({"a": 10, "b": 20}) >>> type_._static_cache_key <stdin>:1: SAWarning: UserDefinedType LookupType({'a': 10, 'b': 20}) will not produce a cache key because the ``cache_ok`` flag is not set to True. Set this flag to True if this type object's state is safe to use in a cache key, or False to disable this warning. symbol('no_cache')
If we did set up such a cache key, it wouldn’t be usable. We would get a tuple structure that contains a dictionary inside of it, which cannot itself be used as a key in a “cache dictionary” such as SQLAlchemy’s statement cache, since Python dictionaries aren’t hashable:
>>> # set cache_ok = True >>> type_.cache_ok = True >>> # this is the cache key it would generate >>> key = type_._static_cache_key >>> key (<class '__main__.LookupType'>, ('lookup', {'a': 10, 'b': 20})) >>> # however this key is not hashable, will fail when used with >>> # SQLAlchemy statement cache >>> some_cache = {key: "some sql value"} Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unhashable type: 'dict'
The type may be made cacheable by assigning a sorted tuple of tuples to the “.lookup” attribute:
class LookupType(UserDefinedType): '''a custom type that accepts a dictionary as a parameter. The dictionary is stored both as itself in a private variable, and published in a public variable as a sorted tuple of tuples, which is hashable and will also return the same value for any two equivalent dictionaries. Note it assumes the keys and values of the dictionary are themselves hashable. ''' cache_ok = True def __init__(self, lookup): self._lookup = lookup # assume keys/values of "lookup" are hashable; otherwise # they would also need to be converted in some way here self.lookup = tuple( (key, lookup[key]) for key in sorted(lookup) ) def get_col_spec(self, **kw): return "VARCHAR(255)" def bind_processor(self, dialect): # ... works with "self._lookup" ...
Where above, the cache key for
LookupType({"a": 10, "b": 20})will be:>>> LookupType({"a": 10, "b": 20})._static_cache_key (<class '__main__.LookupType'>, ('lookup', (('a', 10), ('b', 20))))
New in version 1.4.14: - added the
cache_okflag to allow some configurability of caching forTypeDecoratorclasses.New in version 1.4.28: - added the
ExternalTypemixin which generalizes thecache_okflag to both theTypeDecoratorandUserDefinedTypeclasses.See also
sql_caching
- impl
alias of
sqlalchemy.sql.sqltypes.Unicode
- process_bind_param(value, dialect)
Expects a dictionary of parameter declarations.
- process_literal_param(value, dialect)
Expects a dictionary of parameter declarations.
- process_result_value(value, dialect)
Create parameter index from JSON serialization.
- class flowserv.model.base.WorkflowRankingRun(**kwargs)
Bases:
sqlalchemy.orm.decl_api.BaseIdentifier of a run that was input for a workflow’s post-processing run. Maintains the run identifier and the ranking position. Note that this class does not provide direct access to the handles for the post-processing input runs.
- rank
- run_id
- workflow
- workflow_id
- class flowserv.model.base.WorkflowResultSchema(*args, **kwargs)
Bases:
sqlalchemy.sql.type_api.TypeDecoratorDecorator for the workflow result schema that is stored as serialized Json object.
- cache_ok = True
Indicate if statements using this
ExternalTypeare “safe to cache”.The default value
Nonewill emit a warning and then not allow caching of a statement which includes this type. Set toFalseto disable statements using this type from being cached at all without a warning. When set toTrue, the object’s class and selected elements from its state will be used as part of the cache key. For example, using aTypeDecorator:class MyType(TypeDecorator): impl = String cache_ok = True def __init__(self, choices): self.choices = tuple(choices) self.internal_only = True
The cache key for the above type would be equivalent to:
>>> MyType(["a", "b", "c"])._static_cache_key (<class '__main__.MyType'>, ('choices', ('a', 'b', 'c')))
The caching scheme will extract attributes from the type that correspond to the names of parameters in the
__init__()method. Above, the “choices” attribute becomes part of the cache key but “internal_only” does not, because there is no parameter named “internal_only”.The requirements for cacheable elements is that they are hashable and also that they indicate the same SQL rendered for expressions using this type every time for a given cache value.
To accommodate for datatypes that refer to unhashable structures such as dictionaries, sets and lists, these objects can be made “cacheable” by assigning hashable structures to the attributes whose names correspond with the names of the arguments. For example, a datatype which accepts a dictionary of lookup values may publish this as a sorted series of tuples. Given a previously un-cacheable type as:
class LookupType(UserDefinedType): '''a custom type that accepts a dictionary as a parameter. this is the non-cacheable version, as "self.lookup" is not hashable. ''' def __init__(self, lookup): self.lookup = lookup def get_col_spec(self, **kw): return "VARCHAR(255)" def bind_processor(self, dialect): # ... works with "self.lookup" ...
Where “lookup” is a dictionary. The type will not be able to generate a cache key:
>>> type_ = LookupType({"a": 10, "b": 20}) >>> type_._static_cache_key <stdin>:1: SAWarning: UserDefinedType LookupType({'a': 10, 'b': 20}) will not produce a cache key because the ``cache_ok`` flag is not set to True. Set this flag to True if this type object's state is safe to use in a cache key, or False to disable this warning. symbol('no_cache')
If we did set up such a cache key, it wouldn’t be usable. We would get a tuple structure that contains a dictionary inside of it, which cannot itself be used as a key in a “cache dictionary” such as SQLAlchemy’s statement cache, since Python dictionaries aren’t hashable:
>>> # set cache_ok = True >>> type_.cache_ok = True >>> # this is the cache key it would generate >>> key = type_._static_cache_key >>> key (<class '__main__.LookupType'>, ('lookup', {'a': 10, 'b': 20})) >>> # however this key is not hashable, will fail when used with >>> # SQLAlchemy statement cache >>> some_cache = {key: "some sql value"} Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: unhashable type: 'dict'
The type may be made cacheable by assigning a sorted tuple of tuples to the “.lookup” attribute:
class LookupType(UserDefinedType): '''a custom type that accepts a dictionary as a parameter. The dictionary is stored both as itself in a private variable, and published in a public variable as a sorted tuple of tuples, which is hashable and will also return the same value for any two equivalent dictionaries. Note it assumes the keys and values of the dictionary are themselves hashable. ''' cache_ok = True def __init__(self, lookup): self._lookup = lookup # assume keys/values of "lookup" are hashable; otherwise # they would also need to be converted in some way here self.lookup = tuple( (key, lookup[key]) for key in sorted(lookup) ) def get_col_spec(self, **kw): return "VARCHAR(255)" def bind_processor(self, dialect): # ... works with "self._lookup" ...
Where above, the cache key for
LookupType({"a": 10, "b": 20})will be:>>> LookupType({"a": 10, "b": 20})._static_cache_key (<class '__main__.LookupType'>, ('lookup', (('a', 10), ('b', 20))))
New in version 1.4.14: - added the
cache_okflag to allow some configurability of caching forTypeDecoratorclasses.New in version 1.4.28: - added the
ExternalTypemixin which generalizes thecache_okflag to both theTypeDecoratorandUserDefinedTypeclasses.See also
sql_caching
- impl
alias of
sqlalchemy.sql.sqltypes.Unicode
- process_bind_param(value, dialect)
Expects a workflow result schema object.
- process_literal_param(value, dialect)
Expects a workflow result schema object.
- process_result_value(value, dialect)
Create result schema from JSON serialization.
- flowserv.model.base.by_pos(msg)
Helper to sort log messages by position.
- flowserv.model.base.group_member = Table('group_member', MetaData(), Column('group_id', String(length=32), ForeignKey('workflow_group.group_id'), table=<group_member>), Column('user_id', String(length=32), ForeignKey('api_user.user_id'), table=<group_member>), schema=None)
Each API user has a unique internal identifier and a password. If the active flag is True the user is active, otherwise the user has registered but not been activated or the user been deleted. In either case an inactive user is not permitted to login). Each user has a unique name. This name is the identifier that is visible to the user and that is used for display