Version Python License: Apache 2.0
This is a simple approach to Object relational mapping, that allows you to you focus on objects manipulations and ligcal structures, without the need to write the appropriate queries, insert/update..., for different elements
- Python +3.6 is required, only build-in libraries were used.
- PokemonApp is a pokemon game where I implemented
pyORM
Add: In order to insert an object, all you have to do is:
>>> from pyORM import orm >>> obj_ = yourClass(args....) # 'orm' will identify the object's attributes to generate the DB schema, and will also create the required table if it doesn't exist. >>> dbSession = orm(obj_) # This will also create the required table if it doesn't exist >>> dbSession.add()
Update: In order To save the updates:
Automatic update (using a decorator):
As you can see in classExample.py
, all you need to do is to put is @updateAfterEvent
on top of the method,
once the method returns the updated object (Example: return self
or return Obj
), the decorator will catch it
and apply the updates to the appropriate table in the database
from utils import updateAfterEvent ... class foo: @updateAfterEvent def method1(self, args...): ... return self @updateAfterEvent def method2(self, obj_2, args ...): ... return obj_2
- You can put the decorator in a separate file then import it wherever you'll be using it (Ex:
utils.py
)
Manual update
You can use the function updateObj
(defined in utils.py
):
from utils import updateObj obj_.attr += 10 updateObj(obj_)
Or you can do the same manually:
obj_.attr += 10 dbSession = orm(obj_) updates_ = {k:v[0] for k, v in obj_.__dict__.items() if k[0]!="_"} # pKey is the name of the primary key dbSession.update({pKey: getattr(obj_, pKey)[0]}, **updates_)
Get: This module works in two directions, either it project your python's objects to a relational database, or create/reinitiate previously created objects based on the data saved in the DB.
In this case you shouldn't initialize
orm
with an object like in the previous examples.
dbSession = orm() #Specifying tablename is the only requirement, then you can send any number of arguments (the logical operator between them is 'AND') respSQL = dbSession.filterBy.get(tablename="dummy", arg1="...", arg2=1, ...)[0] # I added [0] because I only wanted the first item from the array, but you can iterate you initiate multiple objects obj_ = yourClass(*respSQL)
Delete: The same as in Get
dbSession = orm() #Specifying tablename is the only requirement, then dbSession.filterBy.delete(tablename="dummy", arg1="...", arg2=1, ...)[0]
All you need to do to implement this module is having the initialized attributes follow this struct:
class dummy: # setting __tablename__ is mandatory __tablename__ = "dummy" def __init__(self, name, args...): ... # Just replace self.name = name with self.name = [name, "VARCHAR(255)", {"PRIMARY KEY": False, "AUTOINCREMENT": False, "FOREIGN KEY {} REFERENCES ...": False}]
- In
self.name[2]
you can set any number of contrains you wish or none, but you must specify whether it's a primary key.
Let make this more interesting and add the decorator!
from myutils import updateAfterEvent class dummy: ... def __init__(self, args...): ... @updateAfterEvent def method(self, args...): ... return self #Or return the object you wish to update
pika = PokemonClass(name="Pikachu", ..., hp=90) crocodil = PokemonClass(name="Crocordil", ... , hp=90) dbSession = orm(pika) if not dbSession.add(): print("{} Added successfully".format(pika.name[0])) dbSession = orm(crocodil) if not dbSession.add(): print("{} Added successfully".format(crocodil.name[0])) #Example of an attack print(pika.hp[0], crocodil.hp[0]) # After the attack 'crocodil' will lose health points and the decorator will save the updated value in the database crocodil = pika.attack(crocodil) print(pika.hp[0], crocodil.hp[0]) # Extract pokemons attributes and instantiate pokemon object dbSession = orm() pokSQL = dbSession.filterBy.get(tablename="dummy", name="Pikachu")[0] pika = dummyPokemonClass(*pokSQL) pokSQL = dbSession.filterBy.get(tablename="dummy", name="Crocordil")[0] crocodil = dummyPokemonClass(*pokSQL) print(pika.name[0], crocodil.name[0]) # This time crocodil's hp will be 80 due to the previous attack print(pika.hp[0], crocodil.hp[0])