StructNoSQL

Structured document based NoSQL client for DynamoDB with automatic data validation and advanced database queries functions.


Keywords
dynamodb, nosql, python
License
MIT
Install
pip install StructNoSQL==2.3.0

Documentation

StructNoSQL

Structured document based NoSQL client for DynamoDB with automatic data validation and advanced database queries functions.

Installation (Python 3.6+ is required) :

pip install StructNoSQL

Example :

# We define a field_type for each field. This is what create the basic validation
# tests, while there is also the possibility to make more complex tests.
class UsersTableModel(TableDataModel):
    userId = BaseField(field_type=str)
    username = BaseField(field_type=str)
    moneyBalance = BaseField(field_type=float)
    class ShoppingCartItem(MapModel):
        itemId = BaseField(field_type=str)
        addedToCartTimestamp = BaseField(field_type=int)
    shoppingCartItems = BaseField(field_type=Dict[str, ShoppingCartItem])
    # The validation tests will work on complex data structures. Like a list or a dict of items.

class UsersTable(BaseTable):
    def __init__(self):
        primary_index = PrimaryIndex(hash_key_name="userId", hash_key_variable_python_type=str)
        super().__init__(table_name="accounts-data", region_name="eu-west-2", 
                         data_model=UsersTableModel(), primary_index=primary_index, auto_create_table=True)


users_table = UsersTable()
shopping_cart_items = users_table.model.shoppingCartItems.query(index_name="userId", key_value="42").first_value()
# Will return in the form of a dict, the shopping cart items that passed the validation tests.
for item_key, item in shopping_cart_items.items():
    print(item.itemId)
    print(item.addedToCartTimestamp)
    # The variables of an item can be accessed as properties, and if they have
    # not been received in the response, you will not get any errors if you
    # try to access them or even if you perform operations on them.

API Summary

IN WRITING, ONLY A FRACTION OF THE DOCS IS DONE

Table :

BaseTable

PrimaryIndex

GlobalSecondaryIndex

Data Models :

TableDataModel

MapModel

Fields :

BaseField

MapField

Operations :

put_record

delete_record

get_one_field_item_from_single_record

get_field

get_multiple_fields

update_field

update_multiple_fields

remove_field

remove_multiple_fields

Operations constructor objects :

FieldGetter

FieldSetter

API Reference

TableDataModel

Class to inherit from to define the DataModel of a table.

Example

from StructNoSQL import TableDataModel, BaseField

class UsersTableModel(TableDataModel):
    accountId = BaseField(field_type=str, required=True)
    username = BaseField(field_type=str, required=True)

BaseField

Primary object to declare the fields of your table, or fields of items in maps and lists.

Arguments

  • name: The name that your field will have in your database, in the data gotten from the database, in your target paths, and that will be expected in set/update operations to the database. You are not required to have the same name for the name parameter and the variable name to which you assigned the BaseField object, yet, we encourage it for code visibility.
    • type: str
    • required: True
  • field_type:
    • type: str|float|int|NoneType|Any|MapModel|list|dict|Dict[type, MapModel]|[type1, type2, ...]|(type1, type2, ...)
    • required: False
    • default: Any
    • Examples :
      from StructNoSQL import TableDataModel, BaseField, MapModel, NoneType
      from typing import Dict
      
      class AccountsTableModel(TableDataModel):
          accountId = BaseField(field_type=str)
          class ProjectModel(MapModel):
              projectName = BaseField(field_type=str)
          projects = BaseField(field_type=Dict[str, ProjectModel], key_name="projectId")
          activePromoCode = BaseField(field_type=[str, NoneType])
  • required: If a required field is missing from any data (both when setting/updating data, and when retrieving it), in a table model or in a MapModel, the data validation will print an error (without raising an exception), and not insert or include the data in the response. If some items in a list or map fails the data validation, only the specific items that fails will not be inserted/not included in the response; the other items that passed the data validation will be included.
    • type: bool
    • required: False
    • default: False
    • Example :
      from StructNoSQL import TableDataModel, BaseField
      
      class AccountsTableModel(TableDataModel):
          accountId = BaseField(field_type=str, required=True)
  • not_modifiable: Act as a read-only parameter. Once a field_value that is not_modifiable is set, trying to change or update its value will cause a rejection from the data validation (without raising an exception). You might use this parameter for your id's fields.
    • type: bool
    • required: False
    • default: False
    • Example :
      from StructNoSQL import TableDataModel, BaseField
      
      class AccountsTableModel(TableDataModel):
          accountId = BaseField(field_type=str, not_modifiable=True)
  • custom_default_value: When you insert/update an item model, all the fields that were not required and that you did not specify will initialize themselves with the field_type that you precised (or the first acceptable field_type if you have a list or tuple of types as the field_type, or the primitive field_type of an object. Learn more about objects primitive types). By specifying a custom_default_value, you can override this behavior just explained, and bring your own default_values to the initialization of a field.
    • type: Any
    • required: False
    • default: None
    • Example :
      from StructNoSQL import TableDataModel, BaseField
      
      class AccountsTableModel(TableDataModel):
          activePromoCode = BaseField(field_type=str, custom_default_value="signupPromoCode")
  • key_name: Reserved for BaseField's with field_type Dict[str, type]. Allows you to define a specific key that will be used in your database_path for navigating inside an item in your field, instead of the default f"{field.name}key". So, without specifying a key_name on our projects field below, the key_name in the database_path to navigate into items of the dict, would be projectsKey (the name of the field, with 'Key' appended to it). By defining our own key_name, we can customize the key to something more fitting to what the key represent, for example : 'projectId'.
    • type: str
    • required: False
    • default: None
    • Example :
      from StructNoSQL import TableDataModel, BaseField, MapModel
      from typing import Dict
      
      class AccountsTableModel(TableDataModel):
          class ProjectModel(MapModel):
              projectName = BaseField(field_type=str)
          projects = BaseField(field_type=Dict[str, ProjectModel], key_name="projectId")

Various infos about the inner-working of StructNoSQL

Objects to primitives types :

  • MapModel : dict
  • Dict: dict
  • List: list

Conversion of floats to Decimals :