Skip to content

Commit

Permalink
Add more examples
Browse files Browse the repository at this point in the history
How to use Group.
How to connect to your database and collection with Connection and Collection.
  • Loading branch information
bmpenuelas committed Dec 10, 2018
1 parent ec2e1e6 commit c40d0b7
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 74 deletions.
133 changes: 65 additions & 68 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,54 +1,61 @@
It's a dict... It's an ORM... It's dictiORM!
It's a dict... It's an ORM... It's dictiORM! :airplane:
==============================================

A tiny MongoDB ORM that takes zero time to setup because docs become simple dicts.
A tiny MongoDB ORM that takes zero time to setup because docs:page_with_curl: become simple dicts **{}**
----------------------------------------------------------------------------------

- Use your database documents **like a simple dictionary variable**. Even in functions that expect a dict!
```python
>>> user_info = dictiorm.Document(collection, {'username': 'user0'})
>>> isinstance(user_info, dict)
True
```
<br>

- You **do not have to predefine models**, in compliance with with MongoDB philosophy of variable document structure.
- Use your database documents **like simple dictionary variables**
```python
>>> user_info = collection.Document({'username': 'user0'})
>>> user_info['age'] = 26 # Create a new field, it is automatically added to the DB.
...
>>> print(user_info['status']) # Access a field that exists in the DB even if you dit not explicitly declare it.
```

- And you still have access to document cache/update, find/count, and **validation**.
<br>

- You **do not need to predefine models**, in compliance with with MongoDB philosophy of variable document structure. Use it even with functions that expect a dict!
```python
>>> isinstance(user_info, dict)
True
```

<br>

- And you still have access to document cache/update, find/count, all the methods of a dict variable and **validation**
```python
>>> validation_funcs = { 'username': lambda x: type(x)==str, 'status': lambda x: type(x)==str }
>>> user_info = dictiorm.Document(collection, {'username': 'user0'}, validators=validation_funcs)
>>> user_info = collection.Document({'username': 'user0'}, validators=validation_funcs)
...
>>> user_info.pop('status') # 'status' was popped. As it is a required field, it will fail validation.
ValueError: Validation failed. Not all the required fields are present. Missing: {'status'}
```
How is it used?
---------------

Simply put: like you use a normal dictionary in Python, with some additional features. You just need:
* `unique_identifier` : The field or fields and values used to select the specific document that you want.

<br>
<br>
<br>

:raising_hand: How is it used?
------------------------------

Simply put: **like you use a normal dictionary in Python**, with some additional features. You just need:
* The field or fields and values used to select the specific document that you want.
Example: `unique_identifier = {'customer_type': 'premium', username': 'user0'}`

* `collection_connection` : The pymongo connector that points to the database.collection that stores that document.
Example: `collection = user_data.db['user_info']`
* A connection to your database and the desired collection. This is made easy with:
`connection = dictiorm.Connection(**database_credentials)`
`collection = connection.Collection('collection_name')`


That's all you need to create a dictiORM object! It will behave like a **dictionary**, and data will be automagically mirrored with a database **document**!

`user_info = dictiorm.Document(collection, unique_identifier)`
`user_info = collection.Document(unique_identifier)`

<br>
<br>

Now you can perform all the operations you are used to:

`user_info['gender'] ` Read a field that was stored in the database.
Expand All @@ -61,53 +68,43 @@ Now you can perform all the operations you are used to:

`user_info.keys()` Get the name of all the fields.

**...
and everything you can do with a regular dictionary!**
...**and everything you can do with a regular dictionary!**
Check out [the examples](/example) for more.

<br>
<br>
<br>

Even pass it to a function that expects a dict:

```python
...
new_user_info = function_that_works_with_dictionaries( user_info )
...
```






Additional functionalities
--------------------------
:bulb: Additional functionalities
---------------------------------

:ballot_box_with_check: `validators` **This is an really useful feature!** You can define a function that evaluates whether if the value of a field fulfills some requirements. If at any moment an invalid value was to be assigned, it would not pass the validation and that modification would never happen. Not in the local object, neither in the database.
Example: `validators = { 'username': lambda x: type(x) == str, 'amount': lambda x: x < 1000 }`


* `initial_values` Fill the doc with additional fields the moment you create it.

* `initial_values` Fill the doc with additional fields the moment you create it if those fields don't have a value already.

Example: `initial_values = {'status': 'registered'}`



* `validators` **This is an extremely useful feature!** You can define a function that evaluates if the value of a field fulfills some requirements. If at any moment an invalid value were to be assigned, it would not pass the validation and that modificatioin would never happen. Not in the local object, neither in the database.
Example: `validators = { 'username': lambda x: type(x) == str, 'amount': lambda x: x < 1000 }`






You can set validators for any number of fields that you want, and let the other fields be changed freely, or...

* `only_validated_fields` you can set this to `True`. This way this dictionary will only be allowed to contain the fields that you have set validators for, and only with values that pass your validation criteria.



* `always_access_db` By default, every modification is mirrored in the database. You can disable this and do it manually whenever you want using:
- yourDoc.update_memory() to read the database and apply changes to your local object.
- yourDoc.update_database() to upload local modifications to the database.



* `yourDoc.delete()` Remove the document from the database. Removal of the object in memory is performed automatically by Python's garbage collection.




v0.2 - Add `Group` class to hold several docs that share some features. More features to come! Questions, comments and contributions always welcome : )

- some_doc.update_memory() to read the database and apply changes to your local object.
- some_doc.update_database() to upload local modifications to the database.



* `some_doc.delete()` Remove the document from the database. Removal of the object in memory is performed automatically by Python's garbage collection.



:paperclip: `Group` You can get the all the documents that match some filter with a single command.
Example: `collection.Group({'status': 'active'})` To get all the documents with status active.
36 changes: 30 additions & 6 deletions example/example.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
# Connect to your database
database_credentials = {'url': url, 'port': port, 'database_name': database_name,
'user': user, 'password': password}
collection_name = 'users_info'
collection = dictiorm.Connection(**database_credentials)[collection_name]
connection = dictiorm.Connection(**database_credentials)

# Now you can access any collection in the database
collection = connection.Collection('users_info')



Expand All @@ -23,14 +25,17 @@

unique_identifier = {'username': 'user0'} # Select the feature(s) that make your document unique

user0_info = dictiorm.Document(collection, unique_identifier) # Create the magic dictiORM dictionary

user0_info = collection.Document(unique_identifier) # Create the magic dictiORM dictionary which
# is connected to the document in your database


print('Is dictionary? ' + str( isinstance(user0_info, dict)) ) # You can use a dictiORM object with
# functions that expect dicts

user0_info['age'] = 25 # Assign new or existing fields as you would with a dictionary, changes are
# saved to the database

print(user0_info['age']) # Read a field from the dictionary, the value is read from the database


Expand All @@ -39,18 +44,19 @@
#%% Example 2
# Extended use case using validators

print('\nUsing validators:')
unique_identifier = {'username': 'user1'} # Select the feature(s) that make your document unique
initial_values = {'age': 18} # Fill the doc with additional initial fields
initial_values = {'age': 18} # Fill the doc with additional initial fields if not already present
validators = { 'username': lambda x: type(x)==str, # If you want to perform validation, you are
'age': lambda x: x>0} # completely free to define the data validation
'age': lambda x: x>0 } # completely free to define the data validation
# functions for as many fields as you want and
# only in the instances that you want
only_validated_fields = True # Choose variable document structure like MongoDB and dicts,
# or fixed structure, for example for user input
always_access_db = True # You decide if every local modification is mirrored in the DB or synced manually


user1_info = dictiorm.Document(collection, unique_identifier, initial_values, validators, only_validated_fields, always_access_db)
user1_info = collection.Document(unique_identifier, initial_values, validators, only_validated_fields, always_access_db)


try:
Expand All @@ -70,3 +76,21 @@

user1_info.delete() # Remove the document from the database (removal of the object in memory is
# performed automatically by Python's garbage collection)




#%% Example 3
# Groups of documents

user2_info = collection.Document({'username': 'user2', 'status': 'active'})
user3_info = collection.Document({'username': 'user3', 'status': 'active'})
user4_info = collection.Document({'username': 'user4', 'status': 'deleted'})


active_users = collection.Group({'status': 'active'}) # Get all the documents with status active


print('\nActive users:')
for user in active_users:
print(user)

0 comments on commit c40d0b7

Please sign in to comment.