[00:16:40] ** hazmat_ has joined us [00:32:09] ** sprout has joined us [00:32:18] ** sprout has left IRC (Remote closed the connection) [04:02:29] [connected at Tue May 17 04:02:29 2005] [04:02:29] <> *** Looking up your hostname... [04:02:29] <> *** Checking ident [04:02:32] <> *** Found your hostname [04:03:02] <> *** No identd (auth) response [04:03:02] <> *** Your host is orwell.freenode.net[orwell.freenode.net/6667], running version dancer-ircd-1.0.35 [04:03:02] [I have joined #peak] [04:03:02] ** orwell.freenode.net set the topic to http://dirtsimple.org/2005/04/generic-functions-reloaded.html [04:32:14] ** hazmat_ has left us [05:37:20] ** [apoirier] has joined us [05:55:33] [apoirier] is now known as apoirier [07:39:03] ** debugger has joined us [07:40:07] hi [09:27:47] ** erikrose has joined us [11:15:20] ** s1x has joined us [11:15:25] lo al [11:22:10] Good morning. [11:36:10] hey guys [11:51:42] yo ho [12:08:26] ** debugger has left IRC () [12:46:49] i'm having this error: NameNotFound: config.MultiKey(, ) [resolvedObj=<__main__.ParqmarApp object at 0xb6c1a60c>] [12:47:19] how can I debug it? It's defined in the [Component Factories] section [12:48:00] is there a way to list the values of the properties and session objects defined there? [12:48:01] Gosh... [12:48:49] There's probably a better way, but, for that sort of thing, I've just been finding where in the PEAK code that error gets thrown and tracing back from there. [12:49:10] :D [12:49:19] i'll try that solution ;) [12:49:20] thx [12:49:31] Not much of a solution, but best of luck. [12:49:46] yes I know :D [13:02:31] ** sprout has joined us [13:06:49] my ini is like this: [13:06:58] [Component Factories] [13:06:59] imobil.model.CategoriaDM = "imobil.storage.CategoriaDM" [13:07:34] my imobil.model has this defined: [13:07:35] CategoriaDM = storage.DMFor (Categoria) [13:08:03] finally my client Component is using this: [13:08:06] CategoriaDM = binding.Obtain (parqmar.model.CategoriaDM) [13:08:22] why is it not finding the component factory? [13:08:39] if I do the "old" CategoriaDM = binding.Make (parqmar.storage.CategoriaDM, offerAs=[parqmar.model.CategoriaDM]) [13:08:41] it works [13:10:30] so I must be doing something wrong in the definition of [Component Factories] [13:16:39] ok, forget it I found it [13:17:10] I am working on two projects, one has basename "imobil" the other one "parqmar" in the INI i was using the wrong module name :S [13:17:14] stupid mistake :( [13:40:17] Hooray for stupid mistakes! [13:40:49] As long as somebody's alive in here, want to take a one-man poll? [13:41:14] I'm updating Ulrich Eck's old object-relational mapping code based on peak.model and peak.storage. [13:42:27] For model.Enumeration subclasses, I'm think of just making the O-R map framework use the .value attribute of the enumerated property as the value to write to the DB. [13:42:48] No plausible situations of wanting to write anything else come to my mind. Do they come to yours? [13:43:53] (Enumeration properties usually return something like 'HatColor.red', as a string. That's not useful for shoving into a SQL DB, and this O-R map is limited in scope to SQL DB's.) [13:52:21] ** apoirier has left IRC ("KVIrc 3.2.0 'Realia'") [13:53:40] where's that code? [13:54:18] so would it be possible to define the value? [13:54:27] The original stuff was posted on 10/10/2003 to the PEAK list. [13:54:38] I've changed it quite a bit, because it was broken in a few places. [13:54:41] * s1x browses the archives [13:54:57] And yes, you get to define the value to be whatever you want. [13:55:05] I often use 4-char strings, for example. [13:56:15] I hope to set up an svn+Trac repository soon. Just haven't had the time yet. [13:56:28] svn+trac is so yummy [13:56:50] * s1x tries to get back to the proposed pool ;) [13:57:05] Proposed pool? [13:57:14] ur one man pool :D [13:57:20] Oh. Poll. Yes. :-) [13:58:02] http://www.eby-sarna.com/pipermail/peak/2003-October/thread.html [13:58:05] where is it? [13:58:38] http://www.eby-sarna.com/pipermail/peak/2003-October/000778.html, and follow the link. [13:58:49] wow O_O I just found this: http://www.eby-sarna.com/pipermail/peak/2003-October/000772.html [13:58:58] it's way simillar to something I've done :D [13:59:17] There were two ORM's posted that month, TableDM and SQLDM. I found SQLDM more promising. [13:59:19] even the fieldmap [13:59:55] wait I have some work on this too [14:00:05] Aye? [14:00:10] if you liked i could put it online somewhere [14:00:20] and u can see my "vision" of things :D [14:00:36] Sure, put it up somewhere. [14:00:55] here's a real example of it's use: [14:00:57] class PhotoDM (BasicTableDM): [14:00:57] db = _DatabaseProperty () [14:00:57] defaultClass = parqmar.model.Photo [14:00:57] TableFields = TableFields ( [14:00:57] lambda self: [ [14:00:58] StringField (name="url"), [14:01:00] StringField (name="thumbnail_url"), [14:01:02] StringField (name="thumbnail_url"), [14:01:04] StringField (name="filename"), [14:01:06] StringField (name="thumbnail_filename"), [14:01:08] ] [14:01:10] ) [14:01:14] so you see it's fairly simillar :D [14:01:17] how quaint [14:02:05] i'll post it on my wiki,there u can take a look since it has syntax highlight and all [14:02:42] Ah, yours is typed. [14:02:53] yes [14:02:56] Mine/Ulrich's is not; it lets model do the typing. [14:03:03] Here's an example of where I'm headed: [14:03:07] it has support for ObjectField, DateField... [14:03:08] class PersonDM(SQLEntityDM): [14:03:08] defaultClass = Person [14:03:09] table = 'people_no_pkey' [14:03:09] fields = ( [14:03:10] ('id', 'id'), [14:03:12] ('name', 'name'), [14:03:15] ('number_of_teeth', 'numberOfTeeth'), [14:03:17] ('hat_color', 'hatColor'), [14:03:20] ) [14:03:22] primaryKey = ('name',) [14:03:25] readOnly = ('id',) [14:04:14] the problem is how to convert, let's say, an object, to a certain SQL table [14:04:24] Actually, I should make a default case so you can just say 'name' instead of ('name', 'name'). [14:04:41] that' would be the best thing :) [14:04:43] Yes, that's the whole point of an O-R mapper. :-) [14:05:08] wait asec, let me show you what i've got... [14:12:18] here ya go: http://wiki.s1x.homelinux.net/Peak/TableDM [14:12:23] it's heavily commented [14:12:30] * erikrose reads. [14:15:50] there's a bug in there... when I delete an object there's still an object in the cache [14:16:17] * erikrose continues reading. [14:16:55] so if you try to get the object associated with a certain oid after you remove it you still get the object. any ideas why? [14:17:20] I'mm about halfway done reading. :-) [14:17:29] kk sry :D [14:19:08] I wish I'd seen this a month ago when I decided whose code to start from. [14:19:22] It looks like it would've been in the running. [14:20:20] i would :D [14:20:31] but i didn't know anyone was working on this [14:21:13] A couple advantages of Ulrich's code I see so far: (1) supports multi-column primary keys, (2) pkeys can be called whatever you want, (3) it doesn't have a race condition in _new(). [14:21:21] I guess I need to be louder about my intentions. :-) [14:21:33] I just hate to preannounce things in case I lose interest or it proves too hard. [14:21:33] ehehe [14:21:43] ehhe [14:21:58] You might want to take a look at TableDM._new(); there's a race condition in there in choosing the new id. [14:22:00] (2) is easily avoidable [14:22:10] what is it? [14:22:18] Let's say you execute this: [14:22:24] new_id, = ~self.db ("SELECT MAX (id) FROM " + self.tableName) [14:22:39] two _new's at the same time? [14:22:52] Then I, on some other computer or something, insert a new row into the table. [14:22:54] they both get the same id... [14:23:07] Then your code continues on, does an INSERT, and crashes into my row. [14:23:13] yep [14:23:14] how to go around it? [14:23:19] Don't Do That. ;-) [14:23:23] lol [14:23:23] :D [14:23:27] then what? [14:23:32] Typically one lets the DB handle autoincrement fields. [14:23:36] sqlite doesn't accept auto increment [14:23:44] Does it do sequences? [14:24:02] sequences? [14:24:22] Yes, sequences are a thing Oracle, Postgres, and probably others support which... [14:24:31] are basically counters off to the side of the tables. [14:24:43] * s1x is n00b in SQL... :S [14:25:09] You'd make a sequence for each of your tables and tell it to start at 1 and count upward 1 at a time. [14:25:29] Then you tell your table to yank a new number out of a particular sequence each time it needs a new id. [14:25:44] It's just a manual, slightly more powerful version of autoincrement. [14:26:15] I do like your interesting idea of making your own descriptors to wrap binding.Make. [14:27:01] So, if SQLite doesn't do autoincrement, maybe it does sequences instead. That's what Postgres does. [14:27:07] http://sqlite.org/faq.html#q1 [14:27:12] it does autoincrement [14:27:19] http://www.sqlite.org/autoinc.html [14:27:23] hehe [14:27:26] :) [14:27:36] but last time i've read it didn't [14:27:43] Well, lucky you. :) [14:28:10] So yeah, to avoid the race, you take advantage of that. You insert the row however you have to to make the DB pick the id for you, [14:28:25] and then you run a SELECT of some kind to figure out what id it used. [14:28:45] (Don't just SELECT max(...); that'd be another race. Usually there's a magic variable or something you can query.) [14:29:08] isn't there still a race condition? [14:29:12] Where? [14:29:21] if two calls do the select [14:29:36] the might get the same (last) inserted row [14:29:38] The magic variable is per transaction or per connection, typically. [14:29:48] which variable is that? [14:29:52] Otherwise, yes, it'd be a race. [14:30:14] It differs for every DBMS; you'll have to look it up for SQLite. It's probably at that URL I pasted. [14:30:31] Can you even have >1 concurrent connection to SQLite? [14:30:58] you can [14:31:02] it uses the file lock [14:31:04] depends on the os [14:31:16] i think it doesn't work on win98 [14:31:46] Whee. [14:31:56] :) [14:32:02] Just as a friendly commendation, I highly recommend Postgres if it will fit your situation. [14:32:04] bulletins has the same race condition :( [14:32:17] It's a joy to use, scalable, and rigorously correct. [14:32:26] Does it?' [14:32:32] yes [14:32:51] that's where I base all my work with peak :D [14:32:58] i'm using python-hosting and the yhave sqlite and mysql [14:33:05] Eeew, it does. [14:33:32] :) [14:33:41] I started with MySQL but pretty quickly outgrew it. [14:33:51] o still don't know how to get the id [14:33:54] MySQL definitely beats rolling your own file formats. :-) [14:33:57] is it not scallable? [14:34:58] "erikrose: I do like your interesting idea of making your own descriptors to wrap binding.Make." -> the TableField? [14:35:07] What, MySQL? [14:35:16] yes [14:35:20] u said u outgrew it [14:35:31] Maybe, maybe not. My trouble with it is it's not rigorously correct. [14:35:43] http://sql-info.de/mysql/gotchas.html [14:36:10] in which cases? [14:36:10] When I got rid of it, it still didn't support transactions or foreign key integrity constraints. [14:36:18] Check that link. [14:36:24] * s1x is reading it [14:38:03] funny [14:38:03] :) [14:38:17] Data corruption is never funny. ;-) [14:39:00] I consider concurrency/locking one of the best things a DB brings. Postgres delivers on it quite well. It basically has the same locking semantics as Oracle. [14:39:57] And yes, to answer your previous question, the TableField. [14:40:44] If the Bulletins example was assumed to only ever have 1 thread running and to be the only thing that updated the DB, then it would work fine: no race condition. [14:41:09] Maybe that's the case, or maybe having good locking was beyond the scope of that example. [14:41:12] but it's supposed to be a web app [14:41:31] I've written single-threaded web apps before, long, long ago. [14:41:57] this is my first real web app [14:42:11] previously i've only worked with python in Desktop applications [14:42:14] Oh, well, if it's real, you should definitely get the locking right. ;-) [14:42:29] I've not used Python on the desktop yet. Been doing web apps for the last 5 years or so. [14:42:31] yes [14:43:00] * s1x wonders how to get the id from the insert... [14:43:01] How long have you been using Python? [14:43:20] hmmm for about two years [14:43:30] It's a fun language. [14:43:33] yes, that's about it [14:43:36] indeed [14:43:52] i really liked it, imo one of the best I've used [14:44:22] It's my current favorite, though I mean to look at Ruby and Common Lisp one of these times. [14:44:41] me too :) [14:44:48] I was limited in my most recent language choice by what I could get to interface with SQLServer and VBScript in ASP. [14:47:34] i would still like to know of you progress in this subject [14:48:22] I'll post to the list as soon as I have something running. [14:48:36] nice :) [14:49:30] I've really been enjoying starting from other people's code for stuff lately. It avoids the fearsome spectre of a blank editor window. [14:50:02] I find it much easier to say "No, I don't like that; let's change it" than trying to figure out the best thing from the entire universe of possibilities. [14:51:31] eheh [14:52:06] even if u have to do it by scratch again? (if u totally disagree with the option) [14:52:18] Well, I try to start from something good. [14:52:37] Or something that can become good by extending it. [14:52:59] I might start from scratch over starting from something badly conceived. [14:54:16] that's what i was thinking :) [14:56:17] do u know why I can't delete my object? [14:56:31] del self.cache[obj._p_oid] [14:56:31] try: [14:56:31] self[obj._p_oid] [14:56:31] assert False [14:56:31] except KeyError: [14:56:31] pass [14:56:33] this fails [14:57:33] fails how? [14:58:09] You mean in TableDM.remove()? [14:58:15] yes [14:58:21] tabledm.remove is not working properly [14:58:39] I'm guessing you have a second reference to the cached object somewhere. Do you think so? [14:58:45] ** debugger has joined us [14:59:07] I'm assuming it's successfully deleting self.cache[obj._p_oid]. [14:59:10] i've read the EntityDM code [14:59:17] it is [14:59:24] i've checked it [14:59:43] but anyway, since it's inside the same transaction it's illegal [14:59:51] What is? [15:00:02] removing and then checking [15:00:15] don't u have to remove in one transition [15:00:18] I don't understand. [15:00:22] and then check in another? [15:00:28] in order to have some effect [15:00:42] del dm[oid] [15:00:42] By "check" you mean "check the DB to see if the DELETE statement worked"? [15:00:52] yes [15:01:14] well actually if the DM.__getitem__ has it [15:01:38] No, when you DELETE, it should show as deleted, within your transaction. Then, when you commit (or before, depending on your "transaction isolation level"), it should show as deleted to other transactions. [15:01:54] Oh, DM.__getitem__? [15:01:55] Hmm. [15:02:16] Your guess is as good as mine there; I just kinda assume the peak.storage stuff works. :-) [15:02:23] If it doesn't, I'll find out soon enough! [15:02:30] ehhehe [15:03:52] i don't get it... :S [15:05:11] Beats me. Add more print statements. [15:05:22] Web apps are a pain to debug, aren't they? [15:05:30] print doesn't even work under ASP. [15:05:39] one of these days maybe I'll reroute sys.stdout or something. [15:07:24] :) [15:07:28] they sure are [15:10:58] Maybe we should write web apps as merely front-ends to commandline apps 9which would be easy to debug). [15:11:18] I suppose theoretically one should be able to unit-test this stuff. :-) [15:11:31] exactly :D [15:14:15] i wonder why it doesn't call the _load method? [15:18:33] Why are print, return, del, and raise special statements? Why can't they be functions? [15:18:49] The other day, I wanted to raise *someTuple, but I couldn't. [15:18:59] eheeh [15:19:18] that would be cool, more flexibility [15:19:27] It'd be another step toward Lisp. [15:19:36] ehehe, yeah [15:19:43] brb [15:21:40] Ever use CherryPy? [15:22:09] It takes the HTTP request and binds its params to Python keyword args. [15:22:39] So myPage.py?thing=5 would end up calling some function and passing "thing=5" as a keyword arg. [15:23:15] But does anybody know what happens when it's not ?thing=5 but rather ?thing[someIllegalChars]=5? [15:23:35] or ?some.other.bad.chars=5? [15:23:43] Otherwise, I like the idea. [15:23:48] It would make for easy testing. [15:28:22] erikrose: i use cherrypy too :) [15:28:29] i'm off, brb [15:28:31] Woohoo! So do you know what happens in that case? [15:28:42] (I don't use CherryPy, but I've looked at it.) [15:30:21] when i get back we0ll talk about it :) [15:30:28] k. Have fun! [16:44:13] i'm back [16:44:15] erikrose: u there? [16:44:17] Welcome. [16:44:21] For 15 minutes I am. :-) [16:44:29] :) [16:44:44] Been making progress. The client syntax is now this: [16:44:47] well, about cherrypy, let me say this it's very straightforward [16:44:52] class PersonDM(SQLEntityDM): [16:44:52] show it [16:44:53] defaultClass = Person [16:44:53] table = 'people' [16:44:53] fields = ( [16:44:54] 'id', [16:44:57] 'name', [16:44:59] ('number_of_teeth', 'numberOfTeeth'), [16:45:02] #('hat_color', 'hatColor'), # sqldm doesn't work with enums yet [16:45:04] ) [16:45:06] but how does it do the conversion? [16:45:06] primaryKey = ('id',) [16:45:09] readOnlyFields = ('id',) [16:45:12] To and from what? [16:45:37] DB==>Python? [16:45:46] DB <=> Py [16:45:55] ** s1x has left IRC (Remote closed the connection) [16:46:50] ** s1x has joined us [16:46:58] sry, gaim just crashed [16:46:59] peak.model does the cardinalities (one-to-many, etc.). peak.storage.SQL does the primitives (Py int to DB int, etc.). [16:47:02] no prob [16:47:07] You didn't miss anything. [16:47:33] All that I see left is enumerations. [16:47:49] i don't use enumerations [16:48:02] they are usually not very extensible [16:48:09] I think and hope peak.model provides the hooks you'd need for crazier stuff. [16:48:30] one of my problems is not knowing the framework all that well [16:48:34] I mean enumerations as in references to another table, that table having relatively static contents. [16:48:58] ah ok [16:49:00] Not MySQL-style enumerations. Those are not very extensible--you're right. [16:49:03] i thought [16:49:05] ues [16:49:06] yes [16:49:08] :) [16:49:37] The only reason those don't work yet is I haven't figured out the right place to hook, and I don't have the stomach to kludge it. [16:49:46] I may well ask pje about that. [16:49:53] do u have the code somewhere I can look at? [16:49:58] It'd take him 30 seconds, where it'd take me hours to dig through the layers. [16:50:02] i would really like to know how do u do the mapping [16:50:08] Here, I'll put it up... [16:50:12] yes [16:50:16] I'll get a Trac going before long. [16:50:34] for example my model has duplication of semantics [16:50:57] you define the type in the model and then in the type storage definition again [16:51:36] Here, the DB doesn't care a whit about the type. [16:52:01] it cares implicitly, doesn't it? [16:53:07] can u give me an example of the convertion? [16:55:15] which modules do u use? [16:55:43] http://peak.telecommunity.com/DevCenter/SqlDm [16:56:22] does this exists since a long time? [16:56:30] PEAK has a bunch of thin wrappers around PyDBAPI DB adapters which make all the primitive conversion transparent. [16:56:37] No, I just put it there 15 seconds ago. ;-) [16:56:46] ** hazmat has joined us [16:56:56] ah [16:56:57] :D [16:59:39] ** hazmat has left IRC (Client Quit) [16:59:54] For my reference, the version I posted is from shortly after my revision 779. [17:00:06] And now I must be off. [17:00:15] See you tomorrow! [17:00:29] kk, bye :) [17:10:18] can someone please explain me when does the DM uses the _load method? [17:10:36] or why is it that my DM is not calling it [17:10:48] ** hazmat has joined us [17:19:54] ** hazmat has left IRC ("This computer has gone to sleep") [17:33:45] yay, i've found it, turns out it was a ghost object and since I wasn't getting any value from it was never a real one. I wonder if it's possible to make it a "real" object besides getting() something from it... [17:34:20] ** hazmat has joined us [17:36:07] ok, _p_activate() did it :) [17:45:17] ** hazmat has left IRC ("This computer has gone to sleep") [18:36:49] I am using [Named Services] to define my database however I would like to offerAs=[storage.ISqlConnection] how can I do that? [18:57:12] ** hazmat has joined us [19:07:14] ** hazmat has left IRC ("This computer has gone to sleep") [19:19:09] ** hazmat has joined us [19:30:06] ** hazmat has left IRC ("This computer has gone to sleep") [19:34:45] ** hazmat has joined us [19:55:18] ** hazmat has left IRC ("This computer has gone to sleep") [20:21:59] ** sprout has left IRC ("Snak 5.0 IRC For Mac - http://www.snak.com") [20:42:42] ** sprout has joined us [20:54:27] ** hazmat has joined us [21:05:50] ** hazmat has left IRC ("This computer has gone to sleep") [21:18:17] ** hazmat has joined us [21:27:47] ** sprout has left IRC ("Snak 5.0 IRC For Mac - http://www.snak.com") [21:29:53] ** hazmat has left IRC ("This computer has gone to sleep") [22:21:12] ** hazmat has joined us [22:57:11] ** s1x has left us [23:12:24] ** debugger has left IRC () [23:28:22] ** hazmat has left IRC ("This computer has gone to sleep")