What is the scope of the fget=
argument upon initialization of a Bulbs class property?
For instance when I am writing:
from bulbs.model import Node, Relationship
from bulbs.property import String
class foobar(Node)
element_type = "foobar"
fget_property = String(fget=some_method)
What some_method
should be to get for the fget_property to be properly defined? Should it perform some operation on the other class properties or can it also be a function of the relations that are liked to an instance of the class, for instance something calling self.outV(some_relation)
?
Here the value for fget
should be a method name that returns a calculated value. The method name should reference a method defined in your Bulbs Model class, and the method should have no parameters.
The fget
method gets called every time you create/update/save the element to the database.
See https://github.com/espeed/bulbs/blob/master/bulbs/model.py#L347
Bulbs uses a Python Metaclass to set the fget
function as a Python property
on the Model
class
you are defining (not to be confused with the Bulbs database Property
, such as String
in your example).
See Python class property (little "p") vs Bulbs database Property (big "P")...
Here's how fget
is set on the Bulbs Model
you define:
class ModelMeta(type):
"""Metaclass used to set database Property definitions on Models."""
def __init__(cls, name, base, namespace):
"""Store Property instance definitions on the class as a dictionary."""
# Get inherited Properties
cls._properties = cls._get_initial_properties()
# Add new Properties
cls._register_properties(namespace)
### ...other class methods snipped for brevity... ###
def _initialize_property(cls, key, property_instance):
"""
Set the Model class attribute based on the Property definition.
:param key: Class attribute key
:type key: str
:param property_instance: Property instance
:type property_instance bulbs.property.Property
"""
if property_instance.fget:
fget = getattr(cls, property_instance.fget)
# TODO: implement fset and fdel (maybe)
fset = None
fdel = None
property_value = property(fget, fset, fdel)
else:
property_value = None
setattr(cls, key, property_value)
See https://github.com/espeed/bulbs/blob/master/bulbs/model.py#L97
For an overview of how Metaclasses work in Python, see:
"Metaclasses Demystified" http://web.archive.org/web/20120503014702/http://cleverdevil.org/computing/78/
UPDATE: Here is a complete working example of a model declaration using an fget
method...
# people.py
from bulbs.model import Node, Relationship
from bulbs.property import String, Integer, DateTime
from bulbs.utils import current_datetime
class Person(Node):
element_type = "person"
name = String(nullable=False)
age = Integer("calc_age")
def calc_age(self):
"""A pointless method that calculates a hard-coded age."""
age = 2014 - 1977
return age
class Knows(Relationship):
label = "knows"
timestamp = DateTime(default=current_datetime, nullable=False)
And here's a full working example for how to use it...
>>> from bulbs.rexster import Graph
>>> from people import Person, Knows
>>> g = Graph()
>>> g.add_proxy("people", Person)
>>> g.add_proxy("knows", Knows)
>>> james = g.people.create(name="James")
>>> julie = g.people.create(name="Julie")
>>> knows = g.knows.create(james, julie)
>>> print james.age
37
>>> print knows.timestamp
2014-08-04 21:28:31