+1  A: 

Database access doesn't get better than SQLAlchemy.

THC4k
I think it does get better. That's what software evolution is all about. SQLAlchemy suffers from the same problems as the Django's models example. Why use more code when less should work like in the example? It's not Pythonic and it involves more complexity. Maybe if it did type inference it would be good, but it doesn't.
Luke Stanley
+1  A: 

Care to explain what about Django's models you don't find straightforward? Here's how I'd do what you have in Django:

from django.db import models
class Task(models.Model):
    title = models.CharField(max_length=...)
    is_done = models.BooleanField()
    def __unicode__(self):
        return self.title

----

from mysite.tasks.models import Task
t = Task(title='Beat old sql interfaces', is_done=True)
t.save()

----

from mysite.tasks.models import Task
print 'Done tasks'
for task in Task.objects.filter(is_done=True):
    print task

Seems pretty straightforward to me! Also, results in a slightly cleaner table/object naming scheme IMO. The trickier part is using Django's DB module separate from the rest of Django, if that's what you're after, but it can be done.

Owen S.
Thanks for the example. It doesn't meed the criteria because object types like CharField and BooleanField are not native Python types. It adds complexity for little good reason, which is especially bad when quickly prototyping. Coders would end up using more code and incorporate entirely new, non Pythonic concepts for little benefit when less could be used instead. Give or take a line or two, I don't see why the code in the question can't work.
Luke Stanley
I disagree. The purpose of the custom field types is to capture criteria about the mapping between the object and the database that cannot be captured by primitive types alone. They actually simplify your mapping! Without them, you have to write all that separately, and your model becomes an incomplete representation of your database entity. The nice thing is, you can generally treat such elements in your code as if they are the fundamental types you want, as the filter and unicode methods show.
Owen S.
What is there to disagree with, if it's simply a different criteria? I guess you mean it's not the solution you would choose still.I probably want either type to model inference or no model.I also think 'bool' would be better than 'from django.db import models' 'models.BooleanField()'. Don't get me wrong, your example is still compelling and it may be the best option *currently* available if a model is required but for prototyping it isn't needed. The goal here is minimalism and simplicity here. ~4 extra lines isn't bad. Little annoying that it has to be in separate files,and more complex.
Luke Stanley
title = models.CharField(max_length=...) could be str() with inference too. Maybe in neccesitates a different interface or such to do it with less typing, clicks or complexity. Maybe that's why web2py comes with it's own GUI but it's not there yet and either way I'm not convinced a new GUI is required. Though a model editor button and better access to MVC concepts may in some ways be more efficient for the moment but the goal here is to prove that wrong.
Luke Stanley
Of course, Mike's lib would simply skip that which is the simplest approach without a model/inference.
Luke Stanley
What I disagree with is your claim that the model fields "add complexity for little good reason" and that the result is "non Pythonic". The latter is perhaps a matter of taste, but the former is definitely false. Take a good look at the field options in Django and ask yourself how you would handle those options without the field. Your answer will probably be "I'll write that myself" or "I'll just write some separate SQL for that", which violates another of your design goals.
Owen S.
If you have constrained your problem domain such that you're using a DB interface like SQLite that's more flexible in some ways, or a limited domain where you can rely on simple inference for what you're missing, then a simpler solution is possible. But then that should have been clarified in your initial request. "Make things as simple as possible, but no simpler."
Owen S.
Do you think the question is better posed now it's edited a little?I think (excuse semicolons due to SO limit):def Task(model): title = ''; isDone = False;or maybe:class Task(): title = str; isDone = bool;is how a model should be defined, Pythonicly.A smarter database wrapper would map to SQL specific types or such from Python natives. Compare this to the Django way, and the Django looks bloated.Maybe I should have thrown in an Einstein quote ;D
Luke Stanley
http://stackoverflow.com/questions/2978138/django-models-sqlalchemy-are-bloated-any-truly-pythonic-db-models-out-thereThere you go, I rewrote the whole thing. Thanks again for helping us get this far!
Luke Stanley
+1  A: 

I've was actually working on something like this earlier today. There is no readme or sufficient tests yet, but... http://github.com/mikeboers/LiteMap/blob/master/litemap.py

The LiteMap class behaves much like the builtin dict, but it persists into a SQLite database. You did not indicate what particular database you were interested in, but this could be almost trivially modified to any back end.

It also does not track changes to mutable classes (e.g. like appending to the list in your example), but the API is really simple.

Mike Boers
Hey Mike, thanks. I built off one from some JSON lib but it's got some bugs. Maybe one gets coded every few days. It's probably easier than Django or such. :)I'll check your example. Will it support JS style, OO dot notation access and creation like: db.dictOrListName.propertyItem ? My JSON lib has such for creation and reading too. I have an XHTML lib I made too that supports OO access too e.g: doc.body.form.firstNameI should get into git stuff I could probably contribute something.
Luke Stanley
+1  A: 

Using web2py:

>>> from gluon.sql import DAL, Field
>>> db=DAL('sqlite://stoarge.db')
>>> db.define_table('taskList',Field('title'),Field('done','boolean')) # creates the table

>>> db['taskList'].insert(title='Beat old sql interfaces',done=False)
>>> db.taskList.insert(title='Beat old sql interfaces',done=False)

>> for task in db(db.taskList.done==True).select():
>>     print task.title

Supports 10 different database back-ends + google app engine.

mdipierro
Thanks for the example! that's a little more compelling in some ways and less in others.Looking at http://web2py.com/examples/default/examples I still see a thin wrapper around SQL mess. It could be much more Pythonic. It's still forcing knowledge SQL, where if I used Mike's suggestion, I'd skip all that entirely.
Luke Stanley