Quick Start

Let’s go through creating a mincepy compatible type and learn how to store, search for, annotate and get the history of objects stored in the database.

Creating types

[1]:
import mincepy
import uuid


class Person(mincepy.SimpleSavable):
    TYPE_ID = uuid.UUID('26798d9e-8c78-430a-ab2c-b17d612ef5fe')
    name = mincepy.field()
    age = mincepy.field()

Here, we’ve defined a simple object and told mincepy:

  1. that the attributes name and age should be stored when saving Person objects, and,
  2. that this type can be identified by the ID given in TYPE_ID

Storing objects

Now, let’s save some people! First we need to connect to our MongoDB database:

[2]:
historian = mincepy.connect('mongodb://127.0.0.1/mince-quick-start', use_globally=True)

The historian is our connection the database and provides methods to perform database related actions on our objects.

Now we can instantiate and save some people!

[3]:
martin = Person(name='Martin', age=34)
martin_id = historian.save(martin)

# Let's save a couple more
sonia_id, upul_id = historian.save(
    Person(name='Sonia', age=30), Person(name='Upul', age=35))

# We can call .save() on the object as we have inherited from SimpleSavable
gavin = Person(name='Gavin', age=34)
gavin_id = gavin.save()

print(martin_id, sonia_id)
5f75cf7b44703dcf435c8500 5f75cf7b44703dcf435c8501

Here we see some of the IDs assigned to our objects. These serve to uniquely identify them and can be used to load them from the database.

Loading objects

Loading objects is as simple as:

[4]:
del martin

martin, sonia = historian.load(martin_id, sonia_id)
print("{}, {}".format(martin.name, martin.age))
Martin, 34

Finding objects

Now, let’s do a search

[5]:
for person in historian.find(Person.age==34):
    print('{}, {}'.format(person.name, person.age))
Martin, 34
Gavin, 34

Modifying objects

Simple, just mutate our object and save!

[6]:
sonia.age = 31
sonia.save()

# Let's double check!
del sonia
sonia = historian.load(sonia_id)
print(sonia.age)
31

Annotating objects

Objects can be annotated by setting a metadata dictionary.

[7]:
historian.meta.set(sonia, dict(city='Copenhagen'))
# Can also do it like this:
martin.set_meta(dict(city='Copenhagen'))
gavin.set_meta(dict(city='Glasgow'))

print(historian.meta.get(gavin))
{'city': 'Glasgow'}

Ok, that’s cool so now what?

Well, we can also search the metadata.

Searching metadata

[8]:
for person in historian.find(Person.age==34, meta=dict(city='Glasgow')):
    print("{}, {}".format(person.name, person.age))
Gavin, 34

Nice.

Indeed, have a look at Historian.find() for a full lowdown on how to find stuff.

So what else can I do?

How about looking into the past?

Version control

[9]:
records = list(historian.snapshots.records.find(obj_id=sonia_id))
for record in records:
    print("{}, {}".format(record.version, record.state))

0, {'name': 'Sonia', 'age': 30}
1, {'name': 'Sonia', 'age': 31}

Here we see two records that were fetched from the archive for Sonia. One with the original age value and the other with the current. MincePy will, by default, keep a record of any modifications you make to objects, think of as being like git, but for objects. We can use a historical record to load the object as it was then:

[10]:
past_sonia = records[0].load()
print("{}, {}".format(past_sonia.name, past_sonia.age))
Sonia, 30

So, that gets you up to speed on the basics of using mincePy. Have a look at the API reference and post an issue here if there is anything else you would like to see documented.