Exercise :
Consider the following code : How would you write BaseModel::get_class_of ?
Simply put :
I have Country class and a City class.
I want to pass this assert :
assert City.get_class_of("country_id") == Country
Put another way : how can I access the class that the country_id attribute referes to ?
<code>
from elixir import *
class MetaModel(EntityMeta):
def __call__(cls,*args,**kw):
id = kw.get("id")
instance = None
# Is this an edit ?
if id :
instance = cls.get(id).one()
instance.from_dict(kw)
# or a creation ?
else:
instance = type.__call__(cls,*args,**kw)
for key in kw:
if key.endswith("_id"):
relation_class = instance.get_class_of(key)
relation_id = kw[key]
set_attribute(instance,key,relation_class.get(relation_id))
return instance
class BaseModel(Entity):
using_options(abstract=True)
repr_attr = "name"
def __repr__(self):
"""
"""
return "<%s '%s' id='%s'>" % (self.__class__.__name__,getattr(self,self.repr_attr,id(self)),self.id)
def get_class_of(relation_name):
"""
self.get_class_of("country_id") == Country
"""
# How do I write this ? can self.mapper.get_property(relation_name) lead to the relation's class ?
pass
class Country(BaseModel):
"""
"""
using_options(tablename = "countries")
name = Field(String)
cities = OneToMany("City")
class City(BaseModel):
"""
"""
using_options(tablename = "cities")
name = Field(String)
country = ManyToOne("Country")
# After elixir setup
algeria = Country("Algeria")
session.flush()
algiers = City("Algiers",country_id=algeria.id)
# The purpose of all this is to have algiers.country == algeria, merely by passing country_id to City.
print algiers.country
# Should print :
# > <Country 'Algiers' id='1'>
</code>
Diez
Am 08.07.2010 um 17:28 schrieb chaouche yacine
<yacinec...@yahoo.com>:
> --
> You received this message because you are subscribed to the Google
> Groups "SQLElixir" group.
> To post to this group, send email to sqle...@googlegroups.com.
> To unsubscribe from this group, send email to sqlelixir+...@googlegroups.com
> .
> For more options, visit this group at http://groups.google.com/group/sqlelixir?hl=en
> .
>
> Why all this Id-business? Assign
> algeria to algiers.country.
>
> Diez
>
My code talks to a black box that gives it only ids. It would be nice if my models adapt to this black box without any middleware code that transforms thoses ids to instances of classes they represent; that's what my models are doing right know, i.e :
<code>
class City(BaseModel):
def __init__(self,*args,**kw):
BaseModel.__init__(self,*args,**kw)
self.country = Country.get(kw.get('country_id'))
</code>
It would be good if I didn't have to do this in each model but rather in BaseModel.__init__ with a generic code.
Thanks.
> Put another way : how can I access the class that the country_id attribute referes to ?
> ...
> def get_class_of(relation_name):
> """
> self.get_class_of("country_id") == Country
> """
> # How do I write this ? can self.mapper.get_property(relation_name) lead to the relation's class ?
Yes. mapper.get_property(relation_name).mapper.class_
> algeria = Country("Algeria")
> session.flush()
> algiers = City("Algiers",country_id=algeria.id)
>
> # The purpose of all this is to have algiers.country == algeria, merely by passing country_id to City.
> print algiers.country
But you have another option here: you could simply flush once more
(after instanciating "algiers" normally and only setting its country_id
attribute) and let the ORM do its job.
Hope it helps,
Gaᅵtan
> > def
> get_class_of(relation_name):
> > """
> >
> self.get_class_of("country_id") ==
> Country
> > """
> > # How do I write
> this ? can self.mapper.get_property(relation_name) lead to
> the relation's class ?
>
> Yes. mapper.get_property(relation_name).mapper.class_
>
> > algeria = Country("Algeria")
> > session.flush()
> > algiers = City("Algiers",country_id=algeria.id)
> >
> > # The purpose of all this is to have algiers.country
> == algeria, merely by passing country_id to City.
> > print algiers.country
>
> But you have another option here: you could simply flush
> once more
> (after instanciating "algiers" normally and only setting
> its country_id
> attribute) and let the ORM do its job.
Thank you Gaëtan, indeed after the second flush the instances are related correctly and transparently. I wonder why it doesn't work like this in a real life example (our current application) though instances are loaded via ModelClass.query.all(). I'll have to look deeper into that nasty code.
Thanks again.