When I create a class/model specifically for the purposes of being embedded into another class/model, a collection is still written for the former in my mongodb database. The aforementioned does not cause any trouble other than the inconvenience of being there, but I'm still wondering if there is any way for a collection not to be written?
I have a nonrel django project as well. Its just a thing django does (and that the nonrel fork has not specifically addressed), that when you define a model that is not abstract or proxy, it is going to generate a collection (table) during a syncdb. Whether you save anything to that collection is further dependent on your code obviously.
If there is some trick to having a concrete model not create a collection in nonrel django, then I am missing something as well.
It's possible if you use abstract=True for that model.
However, you can't use lazy lookup (aka EmbeddedModelField('SomeModelThatsNotYetDefined') yet (https://github.com/django-nonrel/djangotoolbox/issues/15).
Related
I'm building a site using mongodb and django-nonrel. I've read in various places that for mongo, it's better to use straight pymongo than the django ORM. This jives with my experience as well -- django's ORM is awesome for relational databases, but for doesn't give you much that pymongo doesn't do already.
My problem is that I don't know how to set up the database tables (err... "collections") initially without using django's ORM. What do I need to do to cast off the shackles of models.py and syncdb, and just write the code myself?
Seems like somebody should have created a guide for this already, but I can't find one.
A little more detail:
Right now, I'm building models and running syncdb to configure the DB. So far, django's ORM magic has made it work. But I need to do some slightly fancier stuff, like indexing on sub-elements, so I don't think the ORM is going to work for me anymore.
On top of that, I don't use models (other than auth_users and sessions) anywhere else in the project. The real schemas are defined elsewhere in json. I don't want to maintain the model classes when and the json schemas at the same time -- it's just bad practice.
Finally, I have a "loadfixtures" management command that I use to flush, syncdb, and load fixtures. It seems like this would be a very good place for the new ORM-replacing code to live, I just don't know what that code should look like....
With MongoDB you don't need an extra step to predeclare the schema to "set up" collections. The document-oriented nature of MongoDB actually does not enforce a strict schema; documents within a collection may have different fields as needed. It's a different concept to get used to, but the collection will be created as soon as you start saving data to it.
Indexes can be added using pymongo's ensureIndex on a collection.
Similar to the collection creation on data insertion, a collection will also be created if it does not exist when an index is added.
An article that should help you get started: Using MongoDB with Django.
If you're new to MongoDB, you also might want to try the short online tutorial.
I'm working on a django-nonrel project running on Google's AppEngine. I want to create a model for a Game which contains details which are generally common to all sports - i.e. gametime, status, location, etc. I've then modelled specific classes for GameBasketball, GameBaseball etc, and these inherit from the base class.
This creates a problem however if I want to retrieve something like all the Games on a certain day:
Game.objects.filter(gametime=mydate)
This will return an error:
DatabaseError: Multi-table inheritance is not supported by non-relational DBs.
I understand that AppEngine doesn't support JOINs and so it makes sense that this fails. But I'm not sure how to properly tackle this problem in a non-relational environment. One solution I've tried is to turn Game into an abstract base class, and while that allows me to model the data in a nice way - it still doesn't resolve the use case above since its not possible to get objects for an abstract base class.
Is the only solution here to put all the data for all possible sports (and just leave fields that aren't relevant to a specific sport null) in the Game model, or is there a more elegant way to solve this problem?
EDIT:
I'm more interested in understanding the correct way of handling this type of issue in any noSQL setup, and not specifically on AppEngine. So feel free to reply even if your answer isn't GAE specific!
For anyone else who has this issue in the future, here is how I eventually went about resolving it. Keep in mind that this is somewhat of a mongo-specific solution, and AFAIK there is no easy way to solve this just using base nonrel classes.
For Mongo I able to solve this by using Embedded Documents (other noSQL setups may have similar soft-schema type features), simplified code below:
class Game(models.Model):
gametime = models.DateTimeField()
# etc
details = EmbeddedModelField() # This is the mongo specific bit.
class GameBasketballDetails(models.Model):
home = models.ForeignKey(Team)
# etc
Now when I instantiate the Game class I save a GameBasketballDetails object in the details field. So I can now do:
games = Game.objects.filter(gametime=mydate)
games[0].details.basketball_specific_method()
This is an acceptable solution since it allows me to query on the Game model but still get the "child" specific info I need!
The reason multi-table inheritance is disallowed in django-nonrel is because the API that Django provides for those sort of models will often use JOIN queries, as you know.
But I think you can just manually set up the same thing Django would have done with it's model inheritance 'sugar' and just avoid doing the joins in your own code.
eg
class Game(models.Model):
gametime = models.DateTimeField()
# etc
class GameBasketball(models.Model):
game = models.OneToOneField(Game)
basketball_specific_field = models.TextField()
you'll need a bit of extra work when you create a new GameBasketball to also create the corresponding Game instance (you could try a custom manager class) but after that you can at least do what you want, eg
qs = Game.objects.filter(gametime=mydate)
qs[0].gamebasketball.basketball_specific_field
django-nonrel and djangoappengine have a new home on GitHub: https://github.com/django-nonrel/
I'm not convinced, next to the speed of GAE datastore API itself, that the choice of python framework makes much difference, or that django-nonrel is inherently slower than webapp2.
I want to add a layout model to my website (a general settings file), and I want it to be available in the admin interface for configuration.
class Layout(...Model):
primary_header
logo_image
...
This structure shouldn't saved be in a table.
I am wondering if there is a built-in feature that can help me do this.
Thanks
My use case is a configurable layout of the website. Wordpress style. I would like to store that data in a concrete class, without having to implement the file /xml serialization myself.
What about an abstract model? It does not save in the database and is meant to be subclassed, but you are allowed to create instances of it and use its attributes. I assume you want some kind of temporary data structure to pass around that meets the requirements of a model instance.
class Layout(models.Model):
class Meta:
abstract = True
If you for some reason need actual concrete models, and are fine with it creating tables for them, you could technically also re-implement the save() method and make it no-op.
I don't really understand where and how you will be using this, but this is indeed a model that doesn't save.
Personally, I have actually used models that aren't intended to be saved, in a project that uses mongodb and the nonrel django fork. I create models that are purely meant to be embedded into other models as nested sub-documents and I never want them to be committed to a separate collection.
Update
Here is another suggestion that might make things a whole lot easier for your goal. Why not just use a normal django model, save it to the database like normal, and create a simple import/export function to save it out to XML or read into an instance from XML. That way you get 100% normal admin functionality, you can still query the database for the values, and the XML part is just a simple add-on. You can also use this to version up preferences and mark a certain one as active.
I'm developing web page with many type of users, each with different profiles properties. I would like to use built in auth system but:
a) I want to use django-registration.
b) I can point User.get_profile to only one profile model.
How to accomplish that in nice fashion?
I haven't used django-registration so I don't know what it entails. For the second part of your question one way would be to
Associate an UserProfile with every User
Add different kinds of ProfileProperty classes and link to them from UseProfile using a generic relationship.
I know, it is a bit of a stretch.
I'm not an expert nor in python, django or database but I encountered a somewhat similar issue few weeks ago and on #django someone advised me to use Generic relation to achieve that.
I created a UserProfile model that is liked (through a OneToOnefield) to the "true" profile, and using contrib.content-type and generic relation I'm able to use several distinct porfile types.
Note that should work for you if you don't fear to hit you database one more time on each get_profile().
An alternative would be to create a big table that contain all the field for all the profile type and using some kind of hook (or reimplementing a custom save()) to check the retired fields according the profile type. But it look complicated to me, especially if you want to have a lot of different profile type.
Another alternative could be to create a TextField derivated custom field and use it as a storage for a dictionary that you pickle to it on save and unpickle from it on load. With some hacking you could certainly map some of the model attribute to the dictionary key. That would allow a lot of flexibility.
Free hint for ya : I also use fixtures to test my application and forgot to check if the raw parameter of the post_save signal was True to prevent executing the UserProfile creation when using manage.py loaddata. As I had coded the creation of the "true" profile in my post_save callback the exception what kind of weird until I find out what was happening.
Usefull ressource :
defining a profile
generic relation
Is it possible to implement 'expando' model in Django, much like Google App Engine has? I found a django app named django-expando on github but it's still in early phase.
It's possible, but it would be a kludge of epic proportions. GAE uses a different database design known as a column-based database, and the Django ORM is designed to link with relational databases. Since technically everything in GAE is stored in one really big table with no schema (that's why you don't have to syncdb for GAE applications), adding arbitrary fields is easy. With relational databases, where each table stores exactly one kind of data (generally) and has a fixed schema, arbitrary fields aren't so easy.
One possible way you could implement this is to create a new model or table for expando properties that stores a table name, object ID, and a TextField for pickled data, and then have all expando models inherit from a subclass that overrides the __setattr__ and __getattr__ methods that will automatically create a new row in this table. However, there are a few major problems with this:
First off, it's a cheap hack and is contrary to the principles of relational databases.
Second, it is not possible to query these expando fields without even more hacks, and even so it would be ludicrously slow.
My recommendation is to find a way to design your database structure so that you don't need expando models.