Pony ORM define Entity subclass before creating database - python

I'm creating a library that contains Bot class. I want it to be able to store messages logs and some other info in the sql database with the help of the pony orm. Idea is for the bot to accept the path to the database and create it or connect to it if it already exists.
Sadly, it seems that with pony I can only define classes after creation of the database object, needing to inherit from database.Entity class to bind my class to the database.
Obvious solution is to define all classes in the Bot class constructor after the creation of the database, but it seems quite ugly in terms of structure, because I plan those classes to be quite large, and wanted to store them in separate files.
Other hypothetical way is to do following (but I don't know whether that functionality is supported):
from pony import orm
class Message(orm.Entity):
text = orm.Required(unicode)
class Database(orm.Database):
def __init__(self, path):
# super(..).__init__(..)
# bind Message to self
class Bot(object):
def __init__(self, path):
self.database = Database(path)
Yet another possible hypothetical way would be if I could inherit from Database.Entity.
Any ideas? Maybe I can achieve this with another ORMs like SQLAlchemy?

Related

Can we declare PonyORM models without using a database global variable?

Declaring classes that map the db in ponyORM inherits from database as a global variable.
from pony.orm import *
db = Database()
class MyEntity(db.Entity):
attr1 = Required(str)
Is there a way to declare Entities without relying on a global variable?
Maybe something in the line of
class MyEntity(get_db().Entity):
but with control over when the classes are declared so that get_db() returns the appropriate db.
--
We have a few situations in which this would be desirable.
Mixing databases
Using multiple databases with Pony ORM
This is the solution we have currently running. But having inner Classes is ugly, specially because there are a lot of them.
Maybe we could make them go to the global space with global? or import the models within this inner function?
unit testing
Having a global variable causes errors in unit testing or makes it overly complicated because each setUp must check if the database is already bound, and ensure it is the right database.
mapping views
We would like to map views as pony classes. Declare some ORM classes, generate the tables, create the views, declare the ORM view classes.
--
We took a look to other projects that also rely on global objects like flask or celery but we didn't find a solution that would apply to ponyORM.
Maybe it's just not possible and the database object has to be defined and that's it.

Best way to store complex data structures and custom objects server side with Flask

I'm curious if anyone has any suggestions on how to store different data structures and classes in Flask and have those persist for different users.
Let's say for user A and user B I want them to interface with different instances of a class or data structure that will be unique to them. For instance:
class test_class:
def __init__(self, name):
self.name = name
self.dataStructure = someDataStructure()
def do_something(self):
self.dataStructure.doSomething()
a_instance = test_class("a")
b_instance = test_class("b")
These two instances of test_class will persist and be unique to their respective users. What frameworks, libraries, or design patterns would work best for storing objects like these and having them persist server side? I've looked at Flask Sessions but I don't think I can map custom objects to a session key as python classes aren't JSON serializable. I'm new to server development so i'm not sure the best way to go about handeling this kind of problem. Appreciate any help or guidance you offer.

GAE: Convert model to subclass of polymodel

I have an existing GAE app with a reasonably small number of entities, and I would like to update the entities to use polymodel.
I currently have entities like this:
class Mammal(db.Model)
class Reptile(db.Model)
and I'd like to change it to this:
class Animal(polymodel.Polymodel)
class Mammal(Animal)
class Reptile(Animal)
My current plan is to do the following procedure:
Iterate over all of the existing entities to change the class names to some temporary class name. E.g., convert class Mammal(db.Model) to class MammalTmp(db.Model) and convert class Reptile(db.Model) to class ReptileTmp(db.Model). In doing this, I would copy all of the properties of the old class to the new class.
Delete all instances of class Mammal(db.Model) and class Reptile(db.Model).
Iterate over all of the temporary entities to change the class names to the desired class name and type. E.g., convert class MammalTmp(db.Model) to class Mammal(polymodel.Polymodel) and convert class ReptileTmp(db.Model) to class Reptile(polymodel.Polymodel). I would again copy all of the properties of the old class to the new class.
Delete all instances of class MammalTmp(db.Model) and class ReptileTmp(db.Model).
This is a laborious procedure! Is there an easier way to accomplish this?
With the way entities are built and then indexed, no unfortunately there is no other way (as far as I know) to do a similar process. I had to do it when I first wanted to implement polymodels and that's the way I did it. Luckily all of these can be done through code so you don't really have to sit at your computer and change all of that manually.
It's lengthy for sure, but think of all the speed benefits the datastore offers. That's why you have to be careful about creating your models in the first place. I know it's not necessarily easy (as I said I fell in the same hole as you and had to write code for those iterations and changes).
A very good way to do such a process programmatically would be to use MapReduce. A "mapper" could definitely do the trick and help you do that faster and more efficiently. Looking into the sample projects might give you some pointers.
I'm not familiar at all with GAE, but could you just redirect your model definitions through an intermediary? I suppose this wouldn't be any faster than just renaming the base class for all your models, though.
Create a redirect class to start with:
# redirect.py
# note: I don't really know where db comes from...
import gae.db as db
class Model(db.Model):
pass
Then add this line to your model file:
import redirect as db
class Mammal(db.Model):
pass
And since db is now the redirect version, you can change the redirect file..
class Model (db.PolyModel):
pass
But now that I've written it, it sounds like just as much work as manually updating the files, and you lose all access to db. for other basic operations. So, maybe I should just downvote my own answer. :D

Django model polymorphism without Multi-Table Inheritance and additional JOIN

I’m quite new to Django and I’m trying to implement polymorphism inside a Django model, but I can’t see how to do. Before going on I have to say I’ve already tried django-model-utils and django-polymorphism, but they don’t do exactly what I’m looking for.
I have a model called Player, each player has a Role and each Role has different behaviours (i.e. their methods return different values):
class Player(models.Model):
username=models.TextField()
role=models.ForeignKey(Role) #Role is another model with a field called ’name'
def allow_action(self)
#some stuff
class RoleA():
def allow_action(self):
#some specific stuff
class RoleB():
pass
I want that every time I retrieve any instance of Player (in example through Player.objects.filter(…)) every instances has the allow_action() method overwritten by the custom one defined inside the specific class (RoleA, RoleB, etc…) or use the default method provided in Player if the related subclass has no method called with the same name (RoleA, RoleB, etc... are the same role name stored in Player.role.name).
CONSTRAINTS:
Since subclasses (RolaA, RoleB, etc…) do not add new field but only overwrite methods all data have to be stored inside Player’s table, so I don’t want to use Django Multi-Table Inheritance but something more similar to Proxies.
I don’t want to perform additional JOIN to determine specific subclass type since all informations needed are stored inside Player’s table.
I think that this is a standard polymorphism pattern but I don’t see how to implement it in Django using the same table for all players (I've already implemented this polymorphism but not linked to a Django model). I’ve seen Django has a kind of inheritance called “Proxy” but it doesn’t allow to make queries like Player.objects.filter(…) and get instances with method overwritten by custom ones (or at least this is what I understood).
Thanks in advance.
Disclaimer: I've not used django-polymorphic, and this code is based on 5 minutes spent scanning the docs and is entirely untested but I'll interested to see if it works:
from polymorphic import PolymorphicModel
class Role(PolymorphicModel):
name = models.CharField()
class RoleA(Role):
def allow_action(self):
# Some specific stuff...
class RoleB(Role):
pass
class Player(models.Model):
username=models.TextField()
role=models.ForeignKey(Role) #Role is another model with a field called ’name'
def allow_action(self)
if callable(getattr(self.role, "allow_action", None):
self.role.allow_action()
else:
# default action...
Now I believe you should be able to create an instance of Role, RoleA, or RoleB and have Player point to it in the foreign key. Calling allow_action() on an instance of Player will check to see if the instance of Role (or RoleA, RoleB etc) has a callable attribute allow_action() and if so, it will use that, otherwise it will use the default.

Where to put helper functions when not using models and an ORM?

I have to use PyMongo in a Django project, althought I have always used either Django's ORM or Mongoengine. With the old setup, every model had its own method which did some actual work. This time, having to use PyMongo, I don't have the models, and I don't know where to put the helper functions.
Currently I'm writing them inside the models.py file, but I'm not even halfway done that already I feel that this way I'm cluttering the models file (too many little functions).
Do you know a better solution to the problem?
You are not using django ORM, you don't have any models - you should leave models.py empty.
Here's one option you may consider to use.
Create a package called, for example, db. Divide your helper functions into separate scripts according to the entity/collection they are working with. E.g.:
db/
__init__.py
user.py
customer.py
role.py
Other generic helper function you can leave in __init__.py or create a separate module for them.
Additionally, while splitting your current models.py file into these python modules you may notice that most of your helper functions are similar - in that case, think about going with OOP approach, create a python class for each collection, define generic methods etc (and it will look like inventing your own ORM layer).
Hope that helps.
You can organize the helper methods as classmethods of "model"-like classes. After re-organization, the models file may look something like this:
# models.py
class BaseModel(object):
connection = Connection()
db = connection['test']
collection = None # override in subclasss
#classmethod
def get(cls, object_id):
return cls.collection.findOne({"_id": object_id})
class Person(BaseModel):
collection = BaseModel.db['person']
#classmethod
def get_old_people(cls):
return cls.collection.find(...)

Categories

Resources