allancaffee / scaly-mongo Goto Github PK
View Code? Open in Web Editor NEWScalability-centric object document mapper for Mongo on Python
License: BSD 3-Clause "New" or "Revised" License
Scalability-centric object document mapper for Mongo on Python
License: BSD 3-Clause "New" or "Revised" License
Implement "lazy defaults" which make a document return a value for a particular attribute as if it were actually set in the document. If applied to all collection-like fields by default this would make it seem like they were by default empty collections.
class DevelopmentTeam(Document):
structure = {
'name': basestring,
'members': [basestring],
}
This would allow you to assume members
was initialized even in the event that it hasn't been yet. So code like:
>>> for member in dev_team.members:
... print member
Would print nothing rather than crashing with an AttributeError
. Lazy defaults are intended to be read only. The primary challenge is deciding what to do if one of the lazy defaults was modified somehow.
A possible solution to this is only providing them when the object is loaded from the database. Since loaded objects can never be saved back into the database there's no harm in letting someone mess around with them (since there's no reason for them to be changing them anyway).
The way we currently check for unsafe document saves is to just raise an exception if the _id
field is set. Admittedly not very smart, but it works in most cases.
It would be preferable to use a separate class for documents returned from the database that has a was_saved
attribute as True
. (The base Document
class would be updated to have it default to False
.) Then after something has been saved we can readily tell.
>>> themes = MongoProxy().models.Theme
>>> themes.find(sort=[('_id', 1)]) # returns a scalymongo.cursor.Cursor
<scalymongo.cursor.Cursor object at 0x10148edd0>
>>> set([type(x) for x in themes.find(sort=[('_id', 1)])]) # returns scalymongo Documents
set([<class 'scalymongo.schema.ConnectedTheme'>])
>>> themes.find().sort([('_id', 1)]) # returns a pymongo.cursor.Cursor
<pymongo.cursor.Cursor object at 0x10148edd0>
>>> set([type(x) for x in themes.find().sort([('_id', 1)])]) # returns dicts
set([<type 'dict'>])
>>>
pymongo >= 2.2 does not include ObjectId in pymongo.objectid. It can be imported directly from bson.objectid.
If your model has a field that is a dictionary and you have default values set for your model; scaly-mongo will add the default values to the contents of the dictionary field when saving the model.
Example:
from scalymongo import Document
class Theme(Document):
__collection__ = 'themes'
structure = {
'name': unicode,
'layout': [unicode],
'dictionary': dict,
}
required_fields = set([
'name',
'layout',
'dictionary',
])
default_values = {
'layout': list,
'dictionary': dict,
}
theme = Theme({
'dictionary': {'foo': '1', 'bar': '2'},
'layout': [u'foo', u'bar'],
'name': u'Testing 1 2 3',
})
print Theme.find_one({'_id': cls.theme._id})
Prints:
{u'_id': ObjectId('4e7a3f97f64aa0468b00001a'), 'layout': [u'foo', u'bar'], u'name': u'Testing 1 2 3', 'dictionary': {u'bar': u'2', u'foo': u'1', 'layout': [], 'dictionary': {}}}
Without default_values the behavior is as expected:
{u'_id': ObjectId('4e7a43e8f64aa046ee00001a'), u'layout': [u'foo', u'bar'], u'name': u'Testing 1 2 3', u'dictionary': {u'foo': u'1', u'bar': u'2'}}
Currently (v0.1.6) when you call reload()
on a model and it can no longer be found on the server ScalyMongo crashes like:
TypeError: 'NoneType' object is not iterable
It should handle the case that the document is no longer found on the server. Not being found could be caused by:
_id
since this isn't specifically wrong?)Add a shard friendly replacement for DBRefs that can be used to refer to other objects it a way that they can be queried without hitting all shards.
I'm thinking about a syntax similar to the company
field on User
in the example below.
class Company(Document):
structure = {
'name': basestring,
'address': basestring,
}
indexes = {
'fields': ['name'],
'shard_key': True,
}
__database__ = 'test'
__collection__ = 'companies'
class User(Document):
structure = {
'name': basestring,
'company': ScalyRef(Company),
}
In the above example the ScalyRef
would be stored as something like:
{
"db": "test",
"collection": "companies",
"keys": {
"_id": ObjectId("4debbac314dab4a5ec527ba9"),
"name": "10gen",
},
}
This format allows a transparent (or nearly transparent) lookup for a document without causing a global query.
As for accessing the reference I'm open to suggestion as to the best balance of transparency and usability. For instance we could just have the document looked up so that it appears to be a normal embedded document. This is the most transparent interface, but it also causes the structure to diverge violently from how you would expect to interact with a document with that representation. For instance, (given the context of our original example) it would be strange to see an index on User
that pointed to company.keys.name
but not unreasonable.
Another possible interface would be to return a ScalyRef
object which has an attribute or function to look up the document it refers to like in the example below.
company = user.company.get_document()
This is less of an abstraction but it's clearer that an actual query is taking place and the data attributes of the ScalyRef
would still be exposed. This provides the advantage for things like adding a property to the User
like:
@property
def company_name(self):
return self.company.keys.name
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.