I have an application that needs to generate its models on runtime.
This will be done according to the current database scheme.
How can it be done?
How can I create classes on runtime in python?
Should I create a json representation and save it in a database and then unserialize it into a python object?
You can try to read this http://code.djangoproject.com/wiki/DynamicModels
Here is example how to create python model class:
Person = type('Person', (models.Model,), {
'first_name': models.CharField(max_length=255),
'last_name': models.CharField(max_length=255),
})
You can also read about python meta classes:
- What is a metaclass in Python?
- http://www.ibm.com/developerworks/linux/library/l-pymeta.html
- http://gnosis.cx/publish/programming/metaclass_1.html
You could base yourself on the legacy database support of django which allows you to obtain django models from the definitions found in the database :
See here : http://docs.djangoproject.com/en/dev/howto/legacy-databases/?from=olddocs
In particular,
manage.py inspectdb
allows you to create the classes in a file. You should then be able to import them on the fly.
That said, it seems to me that you are on a risky path by doing this.
I have an application that needs to generate its models on runtime.
Take a look at the source code for the inspectdb management command. Inspectdb "Introspects the database tables in the database pointed-to by the NAME setting and outputs a Django model module (a models.py file) to standard output."
How can I create classes on runtime in python?
One way to do this is to use the functions provided by the new module (this module has been deprecated in favor of types since 2.6).
Should I create a json representation and save it in a database and then unserialize it into a python object?
This doesn't sound like a good idea to me.
PS: All said you ought to really rethink the premise for creating classes at runtime. It seems rather extreme for a web application. Just my 2c.
Related
I would like to update My Custom module which was already installed and written in OpenErp v7.0. But i want to migrate to ODOO v8.0. Can anybody please help me with this problem. what is the exact process to upgrade codes and all?
Thanks, Chandu
First you've got to fix the imports from version 7 to version 8
as an example
import osv
will be
import openerp.osv
in version 8
The models used in version 8 are almost the same as in version 7. So there's a big chance that you'll only have to fix the imports.
If the models you've used in version 7 don't exist anymore. you should search for the models that replaced it and rewrite the code to the new models.
Though this is not the correct platform to ask this kind of question
To get you started with NEW API code .. Here are some of the new concepts that you should start to look around on the web.
[1] Record/Recordset and Model
The new version 8.0 of OpenERP/Odoo introduce a new ORM API.
It intends to add a more coherent and concise syntax and provide a bi-directional compatibility.
The new API keeps its previous root design as Model and Record but now adds new concepts like Environment and Recordset.
[2] Model
A model is a representation of a business Object.
It is basically a class that define various class know-how and fields that are stored in database. All functions defined in a Model where previously callable directly by the Model.
This paradigm has changed as generally you should not access Model directly but a RecordSet
To instantiate a model you must inherit an openerp.model.Model:
from openerp import models, fields, api, _
class MyModel(models.Model):
_name = 'a.model' # Model identifer used for table name
firstname = fields.Char(string="Firstname")
[3] Modifing Environment
If you need to modifiy your current context you may use the with_context() function.
self.env['res.partner'].with_context(tz=x).create(vals)
Be careful not to modify current RecordSet using this functionality:
self = self.env['res.partner'].with_context(tz=x).browse(self.ids)
It will modifiy the current Records in RecordSet after a rebrowse and will generate an incoherence between caches and RecordSet.
You can use Openupgrade to migrate your database from openerp7 to odoo.
Download Openupgrade script and run it from terminal:
python migrate.py --config=[your openerp.conf] --database=[your database] --run-migrations=8.0
I have a few databases in MongoDB that I want to create models for dynamically, since there are many databases and I cannot do it manually. Questions:
What should my models.py look like? (Does inspectdb work with mongodb databases or only SQL based dbs?)
Since the database models are created dynamically, how do I code the serializer class to return the dynamic fields?
Thanks in advance.
Django supports an object-relational mapper, that is aimed at traditional relational databases. While there are a number of mongodb packages for Django, none of them support inspectdb to construct your models. Either way, inspectdb is a kludge designed as a one of process to help a one-of migratation away from a legacy system, i.e. you'd build your models.py file once and never run inspectdb again. This is not what you want to do, as you seem to want dynamic models that can be added or altered at runtime.
On the bright side, Django MongoDB Engine has some support for arbitrary embedded models within pre-defined models. But even then they don't seem too supportive of it:
As you can see, generic embedded models add a lot of overhead that bloats up your data records. If you want to use them anyway, here’s how you’d do it...
In summary, try to build your models as best you can to actually match your requirements. If you know nothing about your models ahead of production, then perhaps Django isn't the right solution for you.
Disclaimer: I'm coming from PHP, where there's stdClass, whereas I don't know if something like that exists in Python.
I'm trying to add a few custom properties to Django models and converting them to JSON using json.dumps(). I tried converting them to dicts, but the custom properties don't get converted too. So I'm trying to convert the models to simple objects like PHP's stdClass, so that I can add whatever properties I like to it.
Is this possible, or is there an easier way to add custom properties to a model and JSON-encode it?
Do you want the JSON blob in the database aswell?
If not, then you simple define the properties as usual like normal python methods on the model class, and add the code to export them in your serialiser.
If so, then there is a nice field from django-extensions for this
from django_extensions.db.fields.json import JSONField
You just add the field on your model, and it should handle the conversion to and from python / database representations automagically for you.
I've written some python code to accomplish a task. Currently, there are 4-5 classes that I'm storing in separate files. I'd now like to change this whole thing into a database-backed web app. I've been reading tutorials on Django, and so far I get the impression that I'll need to manually specify the fields and their types for every "model" that I use. This is a little surprising to me, since I was expecting some kind of ORM capability that would just take the existing classes I've already defined, and map them onto a database somehow, in a manner abstracted away from me.
Is this not the case? Am I missing something? It looks like I need to specify all the fields and types in the file 'models.py'.
Okay, now beyond those specifics, does anyone have any general tips on the best way to migrate an object-oriented desktop application to a web application?
Thanks!
That is Django's ORM: it maps classes to tables. What else did you expect? There needs to be some way of specifying what the fields are, though, before you can use them, and that's managed through the models.Model class and the various models.Field subclasses. You can certainly use your classes as mixins in order to use the existing business logic on top of the field definitions.
If you are thinking about a database backend based web app, you have to specify what fields of the data you want to store and what type of the value you want stored.
There is an abstraction that introspects the db to convert it into the django models.py format. But I know not of any that introspects a python class and stores arbitrary data into db. How would that even work? Are the objects, now, stored as a pickle?
You're going to have to check the output, but you can have Django automatically create models from existing databases through one-time introspection.
Taken from the link below, you would set up your database in settings.py, and then call
python manage.py inspectdb
This will dump the sample models.py file to standard out for your inspection. In order to create the file, simply redirect the output
python manage.py inspectdb > models.py
See for more:
http://docs.djangoproject.com/en/dev/howto/legacy-databases/?from=olddocs#auto-generate-the-models
I'm having problems structuring classes in the Model part of an MVC pattern in my Python app. No matter how I turn things, I keep running into circular imports. Here's what I have:
Model/__init__p.y
should hold all Model class names so
I can do a "from Model import User"
e.g. from a Controller or a unit
test case
Model/Database.py
holds Database class
needs to import all Model classes to do ORM
initialization should be performed on first module import, i.e. no extra init calls or instantiations (all methods on Database class are #classmethods)
Model/User.py
contains User model class
needs access to Database class to do queries
should inherit from base class common to all Model classes to share functionality (database persistency methods, parameter validation code etc.)
I have yet to see a real world Python app employing MVC, so my approach is probably un-Pythonic (and possibly a language-agnostic mess on top of that...) - any suggestions on how to solve this?
Thanks, Simon
There is an inconsistency in your specification. You say Database.py needs to import all Model classes to do ORM but then you say the User class need access to the Database to do queries.
Think of these as layers of an API. The Database class provides an API (maybe object-oriented) to some physical persistence layer (such as DB-API 2.0). The Model classes, like User, use the Database layer to load and save their state. There is no reason for the Database.py class to import all the Model classes, and in fact you wouldn't want that because you'd have to modify Database.py each time you created a new Model class - which is a code smell.
Generally, we put it all in one file. This isn't Java or C++.
Start with a single file until you get some more experience with Python. Unless your files are gargantuan, it will work fine.
For example, Django encourages this style, so copy their formula for success. One module for the model. A module for each application; each application imports a common model.
Your Database and superclass stuff can be in your __init__.py file, since it applies to the entire package. That may reduce some of the circularity.
I think you have one issue that should be straightened. Circular references often result from a failure to achieve separation of concerns. In my opinion, the database and model modules shouldn't know much about each other, working against an API instead. In this case the database shouldn't directly reference any specific model classes but instead provide the functionality the model classes will need to function. The model in turn, should get a database reference (injected or requested) that it would use to query and persist itself.