Re: oodb philosophics ;) was: Re: [Zope-dev] Experiments with ORMapping
[EMAIL PROTECTED] said: > This is true in the ZODB, but can be complicated by acquisition. Cheap cop-out: I was planning to avoid acquisition in my "business object" database (which will be a database separate from the Zope ZODB). Personally, I'm not very convinced of the necessity and advantages of acquisition, contrasted with the issues that often arise because acquisition picks a different thing from what the developer thought it would do. It seems OK for a strictly hierarchical collection of web-enabled objects, but I am thinking about a business model, where I don't see a lot of advantages in inflicting behavior onto objects through a containment hierarchy. But then, I didn't read the original paper so please prove me wrong. -- Cees de Groot http://www.cdegroot.com <[EMAIL PROTECTED]> GnuPG 1024D/E0989E8B 0016 F679 F38D 5946 4ECD 1986 F303 937F E098 9E8B ___ Zope-Dev maillist - [EMAIL PROTECTED] http://lists.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope )
Re: [Zope-dev] Experiments with ORMapping
Phillip J. Eby <[EMAIL PROTECTED]> said: >For example, if I am an ISP, and I want to implement an >"active" flag on an "account" object, I would like changing it to >automatically go out and add or remove routing entries and password entries >on my servers when I update the record through my Zope interface (web, >SOAP, or whatever). Could you make a ZODB "Storage" object that supported >this? Maybe. But from an architectural standpoint it would be rather >messy - akin to writing OO code with giant "switch" statements. > class Account(Persistent): def disable(self): map(lambda s: s.end(), self.subscriptions) self.enabled = 0 I don't see a switch statement there. Granted, some jerk could come in and code "account.enabled = 0" somewhere in his code, but that jerk would soon be looking for other employment ;-). I do think that this won't happen very often: instance variables in Python are very implicit, you have to hunt the class code to find them. Instance methods are very explicit, and therefore more likely to be found first. (mostly everything an ISP customer orders is a kind of subscription. A subscription has a start event, a repeat event, and an end event (or state, or whatever you want to call it). Example webhosting: start event is 'create Apache config', repeat event is 'send out yearly invoice' (probably in the base class), end event is 'archive website and remove from Apache config'). Funny you came up with this example. I run an ISP and have spent the last couple of days thinking about just this stuff :-) ___ Zope-Dev maillist - [EMAIL PROTECTED] http://lists.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope )
Re: oodb philosophics ;) was: Re: [Zope-dev] Experiments with ORMapping
Joachim Werner <[EMAIL PROTECTED]> said: >[...]. E.g. how would >you handle objects beloning to more than one container? In SQL this is easy >(Just have a table that matches key pairs from the container table and the >item table). And I don't know any good way of implementing "many-to-many" >relations in object hierarchies. Let alone querying them efficiently. > Probably I'm daft because it is Friday night, but AFAIK ZODB and most OODB's store an object only once, keyed by its object id. The rest is just references through that oid, so objects that belong to more than one container can be added to all these containers and n:m relations are implemented by having a list of objects on both sides. ___ Zope-Dev maillist - [EMAIL PROTECTED] http://lists.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope )
Re: oodb philosophics ;) was: Re: [Zope-dev] Experiments with
[EMAIL PROTECTED] said: > The only problem with this is that lambdas are not safe for TTW > scripting 8^(. I think that TTW scripting and heavy duty application development are very incompatible with each other, so that's not a problem :-) -- Cees de Groot http://www.cdegroot.com <[EMAIL PROTECTED]> GnuPG 1024D/E0989E8B 0016 F679 F38D 5946 4ECD 1986 F303 937F E098 9E8B ___ Zope-Dev maillist - [EMAIL PROTECTED] http://lists.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope )
Re: oodb philosophics ;) was: Re: [Zope-dev] Experiments with
David Brown <[EMAIL PROTECTED]> said: >But isn't Python a decent query language? Isn't it nice to be able to have >all of the facilities of Python at your disposal when manipulating data, >rather than hoping that whatever database you are using doesn't have a >brain-damaged implementation of SQL? > Yup. Our business objects are sitting on top of my homebrew O/R mapping layer, and I find myself entering the Python shell to do ad-hoc stuff with them more and more often. Especially because stuff that repeats one or two times is easily added as a method on the object for later reference... One nice idea that should be possible in Pythonland as well: a Smalltalk O/R mapping layer called GLORP uses Smalltalk as a query language in a very nice way. Queries are given as Smalltalk blocks (say lambdas), and the mapping layer interprets the block's parse tree in order to spit out equivalent SQL code. Say: Employees.get(lambda e: e.name[:3] == 'Foo') to get all employees that have a name starting with "Foo". ___ Zope-Dev maillist - [EMAIL PROTECTED] http://lists.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope )
Re: oodb philosophics ;) was: Re: [Zope-dev] Experiments with ORMapping
Shane Hathaway <[EMAIL PROTECTED]> said: >That's one reason ZODB is so nice. You can write an application without >writing a formal schema. > One of the reasons I am seriously considering to migrate our production database from PostgreSQL to ZODB. I am about to implement our product database, and it is just too darn complex to bother maintaining SQL tables for it... >Actually OracleStorage and bsddbstorage, recently released, are designed >to address concerns about performance and reliability, and they do an >excellent job at it. And I consider ZODB as "real" an OODB as anything >else. (In some ways it's the best out there IMHO.) > I heard that OracleStorage was quite a bit slower? And from what I've seen from FileStorage, it's a basic transaction log - what can be more reliable than that? Are people using ZODB for non-Zope data? I'd be very interested to discuss things like emulating extents, patterns for indexing, etcetera... ___ Zope-Dev maillist - [EMAIL PROTECTED] http://lists.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope )
[Zope-dev] ZIdle, anyone?
I've cooked up a quick IDLE extension that connects to ZEO and shows a DB Browser, like the class/path browser. It's already great fun (quick lookups through a Tkinter tree control beat the heck out of HTML), and although my Tk is rusty, I think that Tk's HTML widget supports just enough HTML to display management screens (that's step 2). Now, before I go off and reinvent wheels, is this a new idea or not? Code says more than 1000 words: 1. Startup script (change zope and idle locations) -- #/bin/sh PYTHONHOME=/opt/zope/current export PYTHONHOME PYTHONPATH=/opt/python/idle-0.5 PYTHONPATH=$PYTHONPATH:$PYTHONHOME PYTHONPATH=$PYTHONPATH:$PYTHONHOME/lib/python PYTHONPATH=$PYTHONPATH:$PYTHONHOME/Extensions PYTHONPATH=$PYTHONPATH:$PYTHONHOME/ZServer/medusa PYTHONPATH=$PYTHONPATH:$PYTHONHOME/ZServer export PYTHONPATH /usr/bin/python zidle.py -- 2. Zidle script -- if __name__ == "__main__": from ZEO import ClientStorage from ZODB import DB from Zope import ClassFactory global App global Conn global Db storage = ClientStorage.ClientStorage(('', 8001)) Db = DB(storage) Db.setClassFactory(ClassFactory.ClassFactory) Conn = Db.open() App = Conn.root()['Application'] import PyShell, sys sys.argv = ['', '-t', 'ZIdle', '-c', 'from zidle import App, Conn'] PyShell.main() -- 3. Browser - from TreeWidget import TreeNode, TreeItem, ScrolledCanvas from WindowList import ListedToplevel import PyShell class DbBrowser: def __init__(self, dbnode): self.dbnode = dbnode self.init() def close(self, event=None): self.top.destroy() def init(self): self.top = ListedToplevel(PyShell.flist.root) self.top.protocol("WM_DELETE_WINDOW", self.close) self.top.bind("", self.close) self.settitle() self.top.focus_set() sc = ScrolledCanvas(self.top, bg="white", highlightthickness=0, takefocus=1) sc.frame.pack(expand=1, fill="both") item = self.rootnode() self.node = TreeNode(sc.canvas, None, item) self.node.update() self.node.expand() def settitle(self): self.top.wm_title("DB Browser") self.top.wm_iconname("DB Browser") def rootnode(self): return DbBrowserTreeItem(self.dbnode) class DbBrowserTreeItem(TreeItem): def __init__(self, dbnode): self.dbnode = dbnode def GetText(self): try: return self.dbnode.title_and_id() except: return `self.dbnode` def GetIconName(self): try: if self.dbnode.isPrincipiaFolderish: return "folder" else: return "python" except: return "python" def GetSubList(self): sublist = [] for i in self.dbnode.objectIds(): sublist.append(DbBrowserTreeItem(self.dbnode[i])) return sublist def IsExpandable(self): try: return self.dbnode.isPrincipiaFolderish \ and len(self.dbnode.objectMap()) > 0 except: return 0 def main(): from zidle import App DbBrowser(App) if __name__ == "__main__": main() 4. README Hit "dbbrowser.DbBrowser(App)" in the IDLE console and have fun. -- Cees de Groot http://www.cdegroot.com <[EMAIL PROTECTED]> GnuPG 1024D/E0989E8B 0016 F679 F38D 5946 4ECD 1986 F303 937F E098 9E8B ___ Zope-Dev maillist - [EMAIL PROTECTED] http://lists.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope )
Re: [Zope-dev] Re: [Geeks] Re: Interface Meta Data proposal
Guido van Rossum <[EMAIL PROTECTED]> said: >When you've fully debugged an application, you turn both off. >When you've fully debugged a library module, you create two versions: >one with both turned off, for use in fully debugged applications, and >one with pre-conditions on and post-conditions off, for use by other >code that is still in need of debugging. > >I've heard that this works very well, and in Python 3000 (when we have >optional static typing) I would love to add this to Python. If it's >not feature bloat. > It works very well in fully debugged applications. In the 99.99% other applications, advice is to leave the assertions on during production time so your app will fail fast when a bug pops up (profiling will point you to the two assertions that needs to be turned off for acceptable performance). Personally, but I'm talking without too much thinking here, I think support for assertions in Python should be based on generic support for metaprogramming - there's more than DBC that could benefit from that (aspect-oriented programming, etcetera). -- Cees de Groot http://www.cdegroot.com <[EMAIL PROTECTED]> GnuPG 1024D/E0989E8B 0016 F679 F38D 5946 4ECD 1986 F303 937F E098 9E8B ___ Zope-Dev maillist - [EMAIL PROTECTED] http://lists.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope )
Re: [Zope-dev] Re: [Geeks] Interface Meta Data proposal
Jeffrey P Shell <[EMAIL PROTECTED]> said: >But I'm not sure how one would go about setting your meta-data in a way that >is at all natural to Python. I think that exceptions that a method >must\should raise *should* be part of a signature\contract. This is one of >the really cool things about Java. If you use a method, 'readFile' that >says it raises IOError, you *HAVE* to catch that exception (I believe in >order to compile). It's so cool, it really chills your productivity. The moment that Python starts doing that, I'll drop the language like a hot iron. 'Nuff about thermodynamics. Making exceptions statically checked is probably the worst misfeature of Java. The idea is nice, in that it forces you to deal with exceptions, but in reality it gets in the way too soon - when you're still exploring, refactoring, stuff like that you should be able to turn the damn things off. I've got five years of full-time Java programming behind me, so I know what I'm talking about. >But it looks like what you're really wanting is to use >interfaces for documentation purposes, not for contract purposes. Not for >interfaces at this level of the language. Useful documentation, especially contracts, can be useful programmatically so stuff like that should at least be setup so that it is possible to move it into the language. A bit like the @pre and @post tags in Javadoc comments - they're always nice to have as documentation, but when you run iContract over them, they are activated and start checking your code's behavior. >If you don't say you implement >'Cloneable', an exception gets raised (even if you implement the proper >method). Another wart in Java that is nice in theory, but sits in your way in practice. I greatly prefer the Smalltalk "protocols" approach, where implementing an interface is accomplished by implementing the right methods period. The funny thing is, hardly any Smalltalk code ever checks for the interface: the (correct) assumption is that if you hand something over to some other thing that says it wants to iterate over whatever you handed over, you'd better be sure that the thing behaves at least enough like a collection so that it can be iterated over. That's the caller's responsibility (a sort of implicit precondition), and if the caller sends over something else, you get a DoesNotUnderstand exception. Very often I have longed in Java for the possibility of an object to implement a subset of behavior of another object, but that's not possible. For example, if you have a bunch of field labels you stuff in a collection just to be able to do getText()/setText() on them (say for internationalization). Now, I want to add menu labels to that collection, they also have getText()/setText() so they would be good citizens in that collection. Java does not allow that, unless I'm prepared to jump through instanceof/type casting hoops (which is only possible if I'm the one actually calling getText()/setText()). >This is similar to how we sniff things today, but we just do >things like 'if hasattr(obj, "cb_isCopyable") and obj.cb_isCopyable()):' > The usual answer of an OO guru here is that if statements are considered harmful, and that if statements that check object types are considered very harmful. The modern variant is "these are strong refactoring smells". -- Cees de Groot http://www.cdegroot.com <[EMAIL PROTECTED]> GnuPG 1024D/E0989E8B 0016 F679 F38D 5946 4ECD 1986 F303 937F E098 9E8B ___ Zope-Dev maillist - [EMAIL PROTECTED] http://lists.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - http://lists.zope.org/mailman/listinfo/zope-announce http://lists.zope.org/mailman/listinfo/zope )