On Dec 18, 2005, at 8:09 AM, limodou wrote:
At this point I'm puzzled with which one should I persist in: Table
metadata , user-defined class or mapper. Some functions can be found
in either Table metadata or mapper. But user-defined class seems only
be used to make ORM. But in other Python ORM modules, class may be the
most important things. Of cause a mapper can be saved to a
user-defined class, but you should use:
myclass.mapper.XXX
Why not just use myclass.XXX and let the mapper is under the class,
so:
mapper(User, user) will do :
User.mapper = mapper(User, user) automaticly, and all mapper's
function can be used as:
User.select(), User.count(),
that has to do with the idea that I do not want SQLAlchemy to dictate
how an application should be written, and also that i want to
emphasize the autonomy between class and mapper; I dont want this
thing to feel, by default, like ActiveRecord at all, only because
ActiveRecord is so habitual, so comfortable, and yet so limiting.
While I do have it attaching a property called "c", thats as far as
I've gone...the possibility of "select", "select_by", etc. being
added to a class, are all things that i think not every application
will want, and I worry about polluting the namespace of a class that
has its own idea what those various names should mean; this is also
why it doesnt even attach "mapper" to the class automatically. in
one example I have it attaching "lazymapper" and "eagermapper"
instead. its not clear to me that "Class.mapper", much less
"Class.select", "Class.get", "Class.save()" is always what someone
will want (in the case of save(), I would never want that actually,
as i think "save-as-you-go" is somewhat of an antipattern that leads
to problems as soon as object graphs get intricate...hence
UnitOfWork. But again I wouldnt want to prohibit the possibility of
an app that wants to do that).
A serious application might make up its own base stereotype for
domain objects which will handle this issue in its own way, much in
the way you are already doing in your example. Other applications
might prohibit domain objects from having any mapping logic attached
to them. Also, method names like "select", "get", etc. are pretty
common...it would be pretty intrusive to have all those names added
to every class by default.
So thats one side of it; that SQLAlchemy is not a framework, and
wants to make as few assumptions as possible about how it will be
used...thats a job for...well frameworks. and while I have seen that
the Python world has this *tremendous* desire for "please tell me how
to write my application"-style frameworks, there are still alot of
people, probably who spend a lot less time blogging, who dont use
"out of the box" frameworks...they write our own based on the needs
of the application. as one of those people myself, thats the space
that I write my stuff for.
I do think the behavior would be handy to have as an option.
Originally, I was going to build a whole ActiveRecord adapter for
this. But I didnt want to get distracted writing a whole different
design paradigm which, while useful, would possibly dilute the more
unique "datamapper" paradigm I was trying to get across. And theres
actually someone working on an ActiveRecord adapter anyway right
now. I think an application should be able to use SQLAlchemy in this
way. But it should be strictly a "special case" of its functionality.
I thought about a bunch of ways to do this, like using a Mixin
class. But a Mixin class, while being the regular OO way to do this,
means your domain model has this persistence-specific name declared
all over it. So I think the nicest way to make this option available
right now, in lieu of some kind of "active record" adapter, is
probably like this:
assign_mapper(Category, categories, **kwargs)
which is equivalent to what you are looking for:
m = mapper(Category, categories, **kwargs)
Category.mapper = m
Category.c = m.c
Category.select = m.select
Category.commit = (some function to call objectstore.commit())
... etc ...
and probably would have some options:
# include only certain attributes
assign_mapper(Category, categories, include_attributes=['select',
'select_by'])
# exclude certain attributes
assign_mapper(Category, categories, exclude_attributes=['get',
'get_by'])
# use an existing mapper , attach to its primary class
assign_mapper(mymapper)
etc. And I thought the class may be like a mixturer of the
user-defined class and mapper. But what I thought may limit the
mapper's effort. So if there could be a easy way to combine the
user-defined class and mapper for some simple circumstance. I'm sorry
for my English. Can you understand me?
And I think I can do more in the user-defined class:
class BaseTable(object):
def get(cls, id):
r = cls.mapper.get(id)
return r
get = classmethod(get)
def save(self):
objectstore.commit(self)
class Category(BaseTable):
def __init__(self, title=None):
self.title = title
def __repr__(self):
return "title=%s" % self.title
class Feed(BaseTable):
def __init__(self, category_id=None, title='', link='',
description=''):
self.category_id = category_id
self.title = title
self.link = link
self.description = description
def __repr__(self):
return "title=%s, link=%s, description=%s" % (self.title,
self.link, self.description)
Feed.mapper = mapper(Feed, RssFeed)
Category.mapper = mapper(Category, RssCategory, properties = {
'feeds' : relation(Feed.mapper, private=True)
}
)
I'm not very familiar with metaclass, so I made a base class
BaseTable, it can do some magic things. So my class can do somethings
which the mapper should do. And I can also user obj.save() to replace
in objectstore.commit(obj). And what I want may be just short typing.
Just some thought, you can think about :)
--
I like python!
My Blog: http://www.donews.net/limodou
NewEdit Maillist: http://groups.google.com/group/NewEdit
-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through
log files
for problems? Stop! Download the new AJAX search engine that makes
searching your log files as easy as surfing the web. DOWNLOAD
SPLUNK!
http://ads.osdn.com/?ad_idv37&alloc_id865&op=click
_______________________________________________
Sqlalchemy-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/sqlalchemy-users
-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems? Stop! Download the new AJAX search engine that makes
searching your log files as easy as surfing the web. DOWNLOAD SPLUNK!
http://ads.osdn.com/?ad_idv37&alloc_id865&op=click
_______________________________________________
Sqlalchemy-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/sqlalchemy-users