[TurboGears] Re: Adding transactions to @expose
On Wed, 2005-11-16 at 13:45 -0500, Jonathan LaCour wrote: Given that this is also possible, it seems like there are several different ways to do this off the top of my head: 1. WSGI middleware (I think) 2. CherryPy filters 3. SQLObject modifications 4. Decorators 5. Some mixture of the above 1. Unfortunately, CherryPy really only has very basic WSGI support - I don't know of any reasonable way to hook WSGI middleware up to Cherrypy at this point (maybe in a future release). 2. Filters in CherryPy won't work either, they don't allow you to wrap the request and I don't think there is any way to guarantee that they are actually run - especially if an exception occurs. 3. SQLObject modifications would be great, but until they are done we'll need to have an interim solution. 4. Which leaves decorators. My plan now is to implement a transaction decorator which will look something like: def in_transaction(func): hub = AutoConnectHub() def newfunc(*args, **kw): hub.begin() try: func(*args, **kw) except cherrypy.HTTPRedirect: hub.commit() raise except: hub.rollback() raise else: hub.commit() newfunc.func_name = func.func_name newfunc.func_doc = func.func_doc return newfunc The expose decorator will check the config / it's parameters and if a transaction is desired it will wrap itself in the in_transaction decorator. This doesn't give us strict per-request transactions if you have database code in your cherrypy filters. But I think any database code in filters would probably mostly be doing reads, so this doesn't seem to be a huge issue. It is probably possible to monkeypatch CherryPy to give us true per-request transactions if we really need them. The AutoConnectHub.begin method checks to see if we're already in a transaction, so calling one transaction-wrapped method from another will result in them both running in one transaction. I think this is the desired default behavior. If you need more transaction stuff beyond this, you can always write your own decorators to do things like nested transactions. And if there is enough demand we can add support for such things to TG in the future. Of course, if you want you can disable all of this automatic transaction stuff in the config and handle transactions yourself or not use transactions / database at all. Sean Cazzell
[TurboGears] Re: validation_error is going away right?
JW, That is in SVN now - if your method has a has_errors var it will get called instead of validate_error. Sean Cazzell On Thu, 2005-11-17 at 17:02 +, [EMAIL PROTECTED] wrote: I read in a post that validation_error was going away. Kevin said, That's a good point. If we deprecate validation_error, then the method can just be called directly and you can check form_errors to see if there's a problem. I think this also means that an invalid exception would never be raised. It simplifies the code, but it does also eliminate a visual reminder to check for errors. Maybe that's not so bad, though. The idea being that the method being called would receive a has_errors argument. The example Kevin gave is below: @turbogears.expose(input_form=myform) def save(self, name, address, age, has_errors): if has_errors: return self.index() Did this change ever make it into turbo-gears? I've been playing with validators and have really grown to not like the validation_error method of dealing with problems :). I'd really like to know what the new-method will be, if there is going to be one. Thanks, jw
[TurboGears] Re: Wonky internet
Speaking of internet connections - I am going to be out of town until Sunday, on vacation at a place with *no* internet connection, so I'll have to get caught up on the list Sunday night. I'm pretty close to having something ready to commit on the new expose decorator front. Things will be fully backwards compatible (expose will still accept and process validators and inputform args). The big changes are splitting the validators and inputform stuff out of expose into other decorators and adding implicit transaction support to expose. I'll throw up some docs on the wiki prior to committing. Have a nice weekend everyone. Sean Cazzell On Thu, 2005-11-17 at 09:15 -0500, Kevin Dangoor wrote: My internet connection is acting up, and they wont be able to get a tech out until tomorrow (Friday) morning. That means email from me will be extra sporadic. Also, next week my email availability will be very spotty. I'm going to try to spot and reply to messages about 0.9 development as top priority. Kevin -- Kevin Dangoor Author of the Zesty News RSS newsreader email: [EMAIL PROTECTED] company: http://www.BlazingThings.com blog: http://www.BlueSkyOnMars.com
[TurboGears] Re: Adding transactions to @expose
On Thu, 2005-11-17 at 12:28 -0500, Kevin Dangoor wrote: Unfortunately, it really needs to use the hub that's in use by the model classes... from a random model.py: __connection__ = AutoConnectHub() # (or PackageHub) class Foo(SQLObject): ... In a multi-application world, it'll be possible to have different parts of a site going to different databases. that won't be the common case, though. Sticking to the common case, we just need a nice way to get ahold of the hub in question. There are probably a small handful of ways we could find the model module and get the hub from it. Unfortunately, I'm out of time for exploring that now, and I'll be offline for a while. I hope I'll be able to get back online at least briefly later today... Kevin, I was worried that I might have to get the hub from the model. I would definitely like to support the multiple-apps case if at all possible. I have to take off as well, I'll look into this more Sunday when I get home. Sean
[TurboGears] Adding transactions to @expose
There has been a lot of interest on the list of having a way to automatically wrap a request in a transaction. The most obvious way to do this is to add it into expose. Michele has done a great job putting together the relevant information (with suggestions from Ian Bicking) on ticket #80 here: http://trac.turbogears.org/turbogears/ticket/80 Since I am already doing some hacking on expose (moving the validator and inputform functionality out to separate decorators) I thought I'd pick this one up. My question is - do we want this on by default, or do we want to explicitly enable it with a parameter to expose? Enabled by default (must explicitly disable): @expose(transaction=False) Disabled by default (must explicitly enable): @expose(transaction=True) Obviously the latter is backwards compatible, but if everyone is going to want a transaction for all of their controller methods, maybe it should be enabled by default? Sean
[TurboGears] Re: Adding transactions to @expose
On Tue, 2005-11-15 at 17:31 -0500, Jonathan LaCour wrote: Maybe this could be handled sort of like validators? @turbogears.expose(transaction=True, err_map={Exception : 'generic msg', SQLObjectNotFound : 'specific msg'} def my_method(self): frob = frobbler.frobble() return dict(frob=frob) On an exception being raised, the transaction would automatically be rolled back, and the appropriate error message would be flashed on the page. Just thinking out loud, and this obviously isn't perfect. But, its an important wrinkle to figure out. I would recommend you put this in a separate decorator like this: @turbogears.expose(...) @exception_flash({Exception: 'generic msg'}) def mymethod(self): ... etc ... It may be cool to have an exception_flash decorator built in to turbogears. Though I really wish cherrypy had an event system or better filtering system so we didn't have to push all of this functionality into decorators. Sean
[TurboGears] Re: Adding transactions to @expose
On Tue, 2005-11-15 at 16:34 -0600, Ian Bicking wrote: I think expected exceptions (including redirects) should not roll back the transaction. Unexcepted exceptions (everything else should). However, you should be able to explicitly roll back or commit the transaction if the decorator doesn't do what you want. See, I knew I was forgetting something. I wonder what a reasonable list of expected exceptions that we don't rollback on is? It should probably be short, I don't want to not rollback if someone is expecting it. I agree with Ian on: cherrypy.HTTPRedirect What about: cherrypy.NotFound cherrypy.HTTPError cherrypy.InternalRedirect I think we should include InternalRedirect and not the other two. The list of cherrypy errors can be found in _cperror.py. Sean Cazzell
[TurboGears] Re: The Feed object
Evelind, Looks great! I am +1 on Michele's suggestion to call it FeedController. Also, Entrys should probably be Entries? What do you think about making the title, link, description and such attributes like: class MyFeed(Feed): title = My Simple Feed link = http://www.example.com/feed; description = This is my really simple feed. def items(self): # ... return list of feed entry dict's here My only reason to suggest this is to break up get_feed_data into logical parts so you don't have one monolithic function to generate a feed. If anyone needs to run code to determine the feed title / link / etc at runtime, they can use properties. Sean Cazzell On Sat, 2005-11-12 at 10:32 +0100, Elvelind Grandin wrote: With version 0.9 turbogears will support easy generating of rss/atom feeds. There still some stuff to add like knowledge of wich elements are valid etc. But here is a quicklook at how it looks like now. http://trac.turbogears.org/turbogears/wiki/FeedObject#preview Any suggestions on features or syntax are more than welcome -- cheers elvelind grandin
[TurboGears] Re: TurboGears books update
Kevin, Thanks for the update! Is there any possibility of any of these books being published for free on the web? I have co-authored a couple books (one was even published :P) so I appreciate the work that goes into it (and the need to get paid for all of that time), but an online book could be a great resource. Sean Cazzell On Sat, 2005-11-12 at 08:15 -0500, Kevin Dangoor wrote: There was a lot of discussion last week about a TurboGears book, so clearly there's a lot of interest in it. There's nothing official to announce, but I wanted to let people know that things are afoot. Mark Ramm and Tim Lesher have some independent ideas for TurboGears books, so we may actually have a couple of book projects underway soon. We're coordinating so that the books will serve different purposes. I was contacted directly by two publishers, Apress and Prentice Hall, this week about doing a TurboGears book. It's a good sign when publishers are coming to you, so it looks very favorable that a TurboGears book will be published. There hasn't been any word from O'Reilly yet. An important thing to note here: writing a book is a big project. It's going to be a number of months before a book comes out. Not to worry, though. The documentation will continue to improve and people have submitted quite a lot of documentation to the wiki. Kevin -- Kevin Dangoor Author of the Zesty News RSS newsreader email: [EMAIL PROTECTED] company: http://www.BlazingThings.com blog: http://www.BlueSkyOnMars.com
[TurboGears] Re: Breaking up @expose
On Sat, 2005-11-12 at 14:24 -0500, Kevin Dangoor wrote: Hi Sean, Nothing like a proposal that includes a patch :) I do agree that the monolithic, growing expose is not ideal, and I do want to make it possible (and easy!) to use other decorators, because they can be quite useful. Just to confirm my hunch (without actually looking at your patch :): @turbogears.expose(html=my.template) def save(self, name, address): ...do something... return dict(foo=bar) This will still work just as before. Yep! So the main bit that your patch does is break out any input related behavior and expose parameters into a new decorator. It's not really any more verbose, it's just moving them to a new home. Seems like a good idea on the surface. Correct, all the patch does is move the validator and forminput stuff to a new decorator called unpack. Unpack will always have to be the first decorator on your methods (currently, expose has to be first): @turbogears.expose(html=my.template) ... other decorators can now go here and work! ... @turbogears.unpack(validators={...}, forminput=...) def save(self, name, address): ...do something... return dict(foo=bar) I am hacking on my Paginator class and adding a decorator to it, but need these changes to expose to enable my decorator to work (it needs to be able to get at the method's return dict before it becomes HTML!). Sean Kevin On 11/12/05, Sean Cazzell [EMAIL PROTECTED] wrote: I have opened a ticket for this and submitted a patch (diff of controllers.py only) that splits expose into expose and unpack. Perhaps unpack should be called something else (validate)? http://trac.turbogears.org/turbogears/ticket/113 Sean -- Kevin Dangoor Author of the Zesty News RSS newsreader email: [EMAIL PROTECTED] company: http://www.BlazingThings.com blog: http://www.BlueSkyOnMars.com
[TurboGears] Re: Breaking up @expose
Yep, I contributed some fixes to the Wareweb unpack (in SVN) and now am hacking on TurboGears unpack. I stole the name for lack of better ideas (and thoughts of making TG unpack a bit more like Wareweb unpack). I think it is probably a good idea to use Wareweb-style coercers instead of FormEncode validators in turbogears.unpack and would be willing to submit a patch if Kevin is interested in making the switch. Wareweb and Paste is awesome, I hope to do what I can to get TG using more of it! I have been kicking around the idea of porting CherryPy to Paste (as Ian has done with Webware) so we could run TurboGears completely on top of Paste and take advantage of all the great code Ian has in there (the debugging webcast on Ian's blog should convince anyone). Sean Cazzell On Sat, 2005-11-12 at 13:31 -0600, Ian Bicking wrote: Sean Cazzell wrote: @expose(template=myproject.templates.foo) @unpack(... validators and inputform stuff here ...) def foo(bar): ... Anyway, just because @unpack looks so familiar to me, I thought I'd note a decorator I wrote for unpacking fields and doing some conversions. It's simpler than validators, for cases when you are getting server-generated content back and don't expect errors. http://svn.pythonpaste.org/Paste/Wareweb/trunk/wareweb/packing.py http://pythonpaste.org/wareweb/module-wareweb.packing.html#unpack
[TurboGears] Re: Breaking up @expose
On Sat, 2005-11-12 at 14:49 -0600, Ian Bicking wrote: Sean Cazzell wrote: I think it is probably a good idea to use Wareweb-style coercers instead of FormEncode validators in turbogears.unpack and would be willing to submit a patch if Kevin is interested in making the switch. I think validators are much better for form validation. However, there's lots of cases when there's a security requirement to validate input (or at least a convenience requirement), but the user shouldn't be editing those values and you don't need to provide nice errors when they are invalid. But, to reiterate, I don't think these should ever be used for user input; if you want to be sloppy to start (which is fine) it is better to do the validation manually (e.g., coerce to int manually) because that will look more like what the un-sloppy validation will look like later. variabledecode probably fits in there somewhere as well; it overlaps a little with unpack, but also should be complimentary. Ian in which cases would you recommend the use of the coercers then? I understand you are saying for passing information back that came from the server. I was using them in Wareweb (just experimenting) with URLs like: /viewdoc/43/ @public @unpack def viewdoc(self, doc_id_int): .. do something .. Obviously, doc_id_int is supplied by the user on the URL not from the server - am I not using things in the intended way here? Wareweb and Paste is awesome, I hope to do what I can to get TG using more of it! I have been kicking around the idea of porting CherryPy to Paste (as Ian has done with Webware) so we could run TurboGears completely on top of Paste and take advantage of all the great code Ian has in there (the debugging webcast on Ian's blog should convince anyone). I'd love to see CherryPy run nicely under Paste as well, so if you hit any problems be sure to ping me and I'll try to help. Thanks, I appreciate the encouragement and will take you up on your offer I am sure :) Sean Cazzell
[TurboGears] Re: Paged result set with TG?
Roman, Here is the solution I am currently using. First, I have a Paginator class like: class Paginator(object): def __init__(self, results, per_page, page=0, total=None): if not total: total = results.count() if total per_page*page: raise NotFound self.pages = int(ceil(total / float(per_page))) self.total, self.results = total, results self.per_page, self.page = per_page, page self.has_previous = self.page 0 self.has_next = self.pages-1 self.page def items(self): offset = self.per_page * self.page end = offset + self.per_page return list(self.results[offset:end]) def page_range(self, range=10): if self.page-range 1: start = 1 else: start = self.page-range if page+range self.pages: end = self.pages else: end = self.page+range return range(start-1, end) (Note that this needs to be hacked a bit for efficiency - it should probably use properties and lazy-load total from results.count()) I use it like this in a controller (say to paginate a list of blog comments): posts = Post.select(Post.q.blogID == topic.id, orderBy=id) paginator = Paginator(posts, per_page=25, page=page) return dict(paginator=paginator, blog=blog, posts=paginator.items()) Now in your kid template you have paginator.has_next, paginator.has_previous, etc. The paginator.page_range function will let you do lists of available pages like gooogle does on large search results :) I stole this idea from Django - I have actually ported/stolen a lot of things from Django (some generic views, get_object_or_404, timesince, etc) to TurboGears. Sean Cazzell On Thu, 2005-11-10 at 12:12 -0800, Roman wrote: Hi A piece of code often needed is that which lets you present a large database result set that spans across several HTML pages (that the user can navigate). As in Gooogle. Does TG (or SQLObject) somehow have native support for this? (or will it in the future?) If not, where should I start when using TG, SQLObject and MySQLPagedResultSet? Cheers, Roman
[TurboGears] Re: Error in svn checkout for kid
I can confirm this. It looks like someone may be trying to do something evil (the ../../passwd thing) - but really, who doesn't use shadowed passwd's these days? Sean Cazzell On Tue, 2005-11-08 at 12:31 -0800, [EMAIL PROTECTED] wrote: When running svn co http://www.turbogears.org/svn/turbogears/trunk turbogears, I'm getting this error: svn: Can't open config file '/var/projects/svn/kid/conf/../../passwd' I'm assuming this is an upstream problem? Thanks Chad
[TurboGears] Re: Indentity: flash when login fails ?
William, This is related to ticked #30: http://trac.turbogears.org/turbogears/ticket/30 The patch to get_flash that I have posted there should fix the flash comes 1 page too late problem you describe without the need for an extra page load. Sean Cazzell On Mon, 2005-11-07 at 01:07 -0800, william wrote: I would just add a turboflash in case of failed login (wrong userid or passwd) Thus, In my Provider I've put the folowing code: if (user.passwd!=passwd): turbogears.flash('invalid userid or password') return None But the message does not appears on the page where I'm redirected, except if I click on one of the link there ;-(. Thus the flash comes 1 page too late. Problem come from redirect (I think) wich use (probably) HTTP code 304. How can I says to the browser to refresh the page after a failed login? Thanks William --- http://www.opensource4you.com
[TurboGears] Re: Identity: delete cookie on browser close
No, you haven't missed anything - it isn't possible right now without changes to the identity code. The good news is the identity code is still under heavy development and this sort of thing will be easy to do in the near future (by 1.0 for sure). For now, you could delete this line in identity.filter.send_identity_cookie: cookies[self.provider.identity_cookie]['expires']= timeout Sean Cazzell On Sun, 2005-11-06 at 08:05 -0800, [EMAIL PROTECTED] wrote: Hi, I'm just playing with the identity part of TurboGears and found that I don't know how to set the identity cookie to last only until the browser is closed. Reading some code I found identity.session.timeout, but setting this to 0 just invalidates the login cookie inmediately. Have I missed some obvious way to do this?
[TurboGears] Re: unicode parameters
I don't believe you need to enable the EncodingFilter as TG should encode the output for you. And rather than using _cpFilterList in your class, try putting decodingFilter.on = True in your dev.cfg file. Hopefully this works! Sean Cazzell On Sun, 2005-11-06 at 14:39 -0800, jak137 wrote: Thank you for links. DecodingFilter from CherryPy would probably solve the problem, but I do not use CherryPy directly. My class inherits from turbogears.controllers.Root and when I try to add to it filters in the way it is done in http://www.cherrypy.org/wiki/UnicodeAware: from turbogears import controllers class Root(controllers.Root): _cpFilterList = [DecodingFilter('utf-8'), EncodingFilter('utf-8')] an exception is a result: Traceback (most recent call last): File pren1-start.py, line 20, in ? from pren1.controllers import Root File /home/jak/pren1/pren1/controllers.py, line 15, in ? class Root(controllers.Root): File /home/jak/pren1/pren1/controllers.py, line 17, in Root _cpFilterList = [DecodingFilter('utf-8'), EncodingFilter('utf-8')] TypeError: default __new__ takes no parameters So, is it possible to enable decoding in TurboGears without modifying the module's source code?
[TurboGears] Re: Identity: delete cookie on browser close
Jeff, I think I see where you are going with the separate timeouts - that way the login expires when the browser is closed or the session times out. What do you think about resetting the session timeout on each request? That way the timeout really becomes an idle timeout. This is how banks handle sessions and it seems to strike the right balance between security and convenience. Can we also add a checkbox to the login form along the lines of remember my login and then adjust the timeout accordingly? I would like to be able to set things up so logins expire after ~10 minutes of idle time (or when the browser is closed) if remember login isn't checked, and expire after some really long period if it is. Sean Cazzell On Sun, 2005-11-06 at 17:29 -0500, Jeff Watkins wrote: This raises an interesting point: I think the Identity framework should have separate time-out values for the cookie and the identity session. I think the cookie should default to not having a time out, hence it will be deleted when the browser quits. The identity session will still have a 20 minute lifetime. There are a number of other little tweaks I want to add to the Identity framework's: * Ability to specify the host and path for the cookie * Ability to tie a session cookie to the visitor's IP address * Adding the current identity to the variable provider for template access I got distracted with other work this weekend, but I'd like to get these features included in the next few days. On 6 Nov, 2005, at 4:39 pm, Sean Cazzell wrote: No, you haven't missed anything - it isn't possible right now without changes to the identity code. The good news is the identity code is still under heavy development and this sort of thing will be easy to do in the near future (by 1.0 for sure). For now, you could delete this line in identity.filter.send_identity_cookie: cookies[self.provider.identity_cookie]['expires']= timeout Sean Cazzell On Sun, 2005-11-06 at 08:05 -0800, [EMAIL PROTECTED] wrote: Hi, I'm just playing with the identity part of TurboGears and found that I don't know how to set the identity cookie to last only until the browser is closed. Reading some code I found identity.session.timeout, but setting this to 0 just invalidates the login cookie inmediately. Have I missed some obvious way to do this? -- Jeff Watkins http://newburyportion.com/ Not everything that can be counted counts, and not everything that counts can be counted. -- Albert Einstein
[TurboGears] Re: TurboGears, or why I chose it over Django and Ruby on Rails
On Sat, 2005-11-05 at 09:16 -0500, Kevin Dangoor wrote: People don't realize this, but CherryPy's system is a lot more flexible than people give it credit for, and I like how CP does not require a separate configuration for URLs. Your example here can be handled fairly simply: class Blog: @turbogears.expose() def default(self, slug): ...do something... class Root(controllers.Root): blog = Blog() Also, CP 2.2 is going to add back positional parameters handling for methods. There's a ticket open to do this in TurboGears, and I may just do that as an interim measure until CP 2.2 is out. So, that adds this option: class Root(controllers.Root): @turbogears.expose() def blog(self, slug): ...do something... This would actually allow either of these URLs to work: /blog/slug /blog?slug=slug Kevin, adding back positional params will be awesome. I know you can currently use default, but you are going to have to create a separate class for every exposed method or put some sort of dispatch logic into your Root.default. I do agree that not having to maintain a separate URL mapping file is nice and DRY. Also turbogears.expose validators do not work with positional parameters. I've toyed with various fixes to this - my initial thought was to do introspection on the decorated method, but I think that breaks when you have stacked decorators like @turbogears.expose() @require_group(Admin) def blog(self, slug): ... Maybe we could require that expose always decorate the method directly? It makes things a little more fragile, but it would allow expose to introspect the method it is decorating to get the names of positional parameters. We could allow validators to be specified as either a list or a dict, but what if you want a url like: http://www.example.com/blog/my_slug_here/?page=2 I'm not sure how you are going to specify the validator list for your method: @turbogears.expose() def blog(self, slug, page=0) ... do something here ... Maybe just have a separate positional_validators argument to expose? Kind Regards, Sean Cazzell
[TurboGears] Re: Returning a 404 response
I think this is the way to do it: http://www.cherrypy.org/trunk/docs/book/chunk/ch03.html#id3221100 http://www.cherrypy.org/wiki/HandleErrors Kind Regards, Sean Cazzell On Fri, 2005-11-04 at 09:46 +, Lee McFadden wrote: I haven't really tried this myself yet, but I looked into it and the only thing I could find that may be useful is cherrypy.headerMap[1]. Using this you may be able to alter the response code of the page given certain criteria. - Lee [1] http://www.cherrypy.org/wiki/ReturnVsYield - See the code snippet near the bottom of the page. On 04/11/05, Jeff Grimmett [EMAIL PROTECTED] wrote: I'm a little confused on error handling in TG versus CherryPy itself. The CP site has a few examples of how to ensure that a 404 response is sent for a page that does not exist, but it looks like it would conflict with the use of Kid templates to generate a 'custom' 404 page. Currently, I have a 'default' defined for my Root class; if someone requests a page that does not exist, it falls through to this method and it then uses my 404.kid template to generate a custom not-found page. That's cool so far, but shouldn't a 404 error be sent in the response? When using the 'default' method, I'm sending a '200' response (page found), which is not very useful to crawlers, etc. What's the best way to handle this? Dispose of default() and use the CP error handler instead? -- Things fall apart. The Center cannot hold. - Life as a QA geek, in a nutshell. Best, Jeff
[TurboGears] Coding style question
The TurboGears site suggests PEP 8 style be used but I have noticed CherryPy, SQLObject and TG mostly use mixedCase style for method names. So is the official recommendation PEP 8 but mixedCase methods? Kind Regards, Sean Cazzell
[TurboGears] Re: I broke my TG install :D
Jeremy, I ran into the same issue - there may be an easier way to fix it, but I edited my tg-admin script and commented out the __requires__ = 'TurboGears==0.8a4' line and changed the load_entry_point call to: load_entry_point('TurboGears', 'console_scripts', 'tg-admin')() It worked for me! Does anyone know how to generate the tg-admin script from a SVN tree? I tried python setup.py install_scripts but I get the following error: error: cannot copy tree 'build/scripts-2.4': not a directory Kind Regards, Sean Cazzell On Thu, 2005-11-03 at 13:35 -0800, Jeremy wrote: Ok.. So I tried to upgrade to the svn version of turbogears... I installed svn. Then I downloaded the turbogears latest version by running: svn co http://www.turbogears.org/svn/turbogears/trunk turbogears Then I ran: easy_install RuleDispatch After that: python setup.py develop Now, whenever I run tg-admin, I get: asimov:~/turbogears jeremy$ tg-admin /Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/setuptools-0.6a7-py2.4.egg/pkg_resources.py:1943: UserWarning: Module paste was already imported from /Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/PasteDeploy-0.3-py2.4.egg/paste/__init__.pyc, but /Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/Paste-0.3-py2.4.egg is being added to sys.path warn( Traceback (most recent call last): File /usr/local/bin/tg-admin, line 7, in ? sys.exit( File /Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/setuptools-0.6a7-py2.4.egg/pkg_resources.py, line 236, in load_entry_point return get_distribution(dist).load_entry_point(group, name) File /Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/setuptools-0.6a7-py2.4.egg/pkg_resources.py, line 229, in get_distribution if isinstance(dist,Requirement): dist = get_provider(dist) File /Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/setuptools-0.6a7-py2.4.egg/pkg_resources.py, line 115, in get_provider return working_set.find(moduleOrReq) or require(str(moduleOrReq))[0] File /Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/site-packages/setuptools-0.6a7-py2.4.egg/pkg_resources.py, line 382, in find raise VersionConflict(dist,req) # XXX add more info pkg_resources.VersionConflict: (TurboGears 0.9a0dev-r136 (/Users/jeremy/turbogears), Requirement.parse('TurboGears==0.8a3')) Aparently, there is a version conflict, but I do not know how to resolve this. Thanks! Jeremy
[TurboGears] Re: TurboGears using Microsoft SQL Server?
Randall, I think MS SQL support is currently only in SQLObject CVS. See: http://www.sqlobject.org/News.html#sqlobject-0-8-0 Sean Cazzell On Thu, 2005-11-03 at 16:49 -0800, [EMAIL PROTECTED] wrote: SQL Object's documentation says they support Microsoft SQL Server. However, I haven't seen how to test that-I did test the underlying components they said were necessary. When working through the tutorial I got this message: cd /d/wwwroot/turbogears/wiki20 tg-admin.exe sql create Using database URI mssql://rjb:[EMAIL PROTECTED]:1433/turbogears Traceback (most recent call last): File c:\python24\Scripts\tg-admin-script.py, line 7, in ? sys.exit( File c:\python24\lib\site-packages\TurboGears-0.8a4-py2.4.egg\turbogears\comm and\__init__.py, line 186, in main command.run() File c:\python24\lib\site-packages\TurboGears-0.8a4-py2.4.egg\turbogears\comm and\__init__.py, line 106, in run command.the_runner.run(sys.argv) File c:\python24\lib\site-packages\SQLObject-0.7.0-py2.4.egg\sqlobject\manage r\command.py, line 102, in run runner.run() File c:\python24\lib\site-packages\SQLObject-0.7.0-py2.4.egg\sqlobject\manage r\command.py, line 233, in run self.command() File c:\python24\lib\site-packages\SQLObject-0.7.0-py2.4.egg\sqlobject\manage r\command.py, line 543, in command for soClass in self.classes(require_some=True): File c:\python24\lib\site-packages\SQLObject-0.7.0-py2.4.egg\sqlobject\manage r\command.py, line 255, in classes conn = self.connection() File c:\python24\lib\site-packages\SQLObject-0.7.0-py2.4.egg\sqlobject\manage r\command.py, line 316, in connection return sqlobject.connectionForURI(self.options.connection_uri) File c:\python24\lib\site-packages\SQLObject-0.7.0-py2.4.egg\sqlobject\dbconn ection.py, line 910, in connectionForURI assert self.schemeBuilders.has_key(scheme), ( AssertionError: No SQLObject driver exists for mssql (only sqlite, sapdb, postgr esql, firebird, maxdb, sybase, interbase, psycopg, mysql, postgres)
[TurboGears] tg-admin sql create fails when using ForeignKey
Hello, I am taking a look at TurboGears and following through the getting started guide. I have found that running tg-admin sql create fails with models containing foreign keys because the create table statements are issued in the wrong order. I am using postgresql. Here's an example model: class Site(SQLObject): name = StringCol(length=25) members = MultipleJoin('Member') class Member(SQLObject): site = ForeignKey('Site', unique=True) username = StringCol(length=25) Running tg-admin sql sql outputs the following: CREATE TABLE member ( id SERIAL PRIMARY KEY, site_id INT UNIQUE, CONSTRAINT site_id_exists FOREIGN KEY (site_id) REFERENCES site (id) , username VARCHAR(25) ); CREATE TABLE site ( id SERIAL PRIMARY KEY, name VARCHAR(25) ); And tg-admin sql create fails on the CREATE TABLE member statement as the site table does not exist yet. Is this a known limitation, or is there some way around this? Kind Regards, Sean Cazzell