当前位置:  开发笔记 > 编程语言 > 正文

Django Models/SQLAlchemy臃肿!有没有真正的Pythonic数据库模型?

如何解决《DjangoModels/SQLAlchemy臃肿!有没有真正的Pythonic数据库模型?》经验,为你挑选了1个好方法。

" 让事情变得尽可能简单,但并不简单. "

我们能找到修复Python数据库世界的解决方案吗?

更新:Alex Martelli编写了一个'lustdb'原型 - 如果你知道任何有多个后端的轻量级,高级数据库库,我们可以包含语法糖蜂蜜,请称重!

from someAmazingDB import *  
#we imported a smart model class and db object which talk to database adapter/s
class Task (model): 
    title = ''
    done = False #native types not a custom object we have to think about!

db.taskList = []
#or
db.taskList = expandableTypeCollection(Task) #not sure what this syntax would be

db['taskList'].append(Task(title='Beat old sql interfaces',done=False))
db.taskList.append(Task('Illustrate different syntax modes',True)) # ok maybe we should just use kwargs

#at this point it should be autosaved to a default db option

#by default we should be able to reload the console and access the default db:

>> from someAmazingDB import *
>> print 'Done tasks:'
>> for task in db.taskList:
>>     if task.done:
>>         print task.title
'Illustrate different syntax modes'

我是Python,webPy和Cherry Py以及KISS的粉丝.

我们正在谈论自动 Python到SQL 类型转换或NoSQL. 我们不必完全兼容SQL!只是一个可扩展的子集或忽略它!

Re:模型更改,可以询问开发人员何时尝试更改它或具有一组合理的默认值.

这是一个挑战:上面的代码应该只需要很少的修改或思考.当我们知道更好的时候,为什么我们必须忍受妥协呢?

在2010年,我们应该能够在睡眠中编写可扩展的简单数据库.

如果你认为这很重要,请upvote!



1> Alex Martell..:

您要求的内容无法在Python 2中完成.无论如何,出于非常具体的原因.你想写:

class Task(model): 
    title = ''
    isDone = False

在Python 2,什么,什么 model可能是,这不能永远让你预测这两个领域的任何"订货",因为语义class声明如下:

    执行身体,从而准备一个 dict

    找到元类并运行其特殊方法

无论元类可能是什么,第1步都破坏了字段顺序的任何可预测性.

因此,您需要使用位置参数,在代码段中:

Task('Illustrate different syntax modes', True)

不能将参数的值与模型的各个字段相关联.(试图通过类型关联来猜测 - 希望没有两个领域具有相同的类型 - 将比你表达的使用db.tasklistdb['tasklist']无差别且可互换的愿望更加可怕.

Python 3中的一个向后不兼容的更改是专门为处理此类情况而引入的.在Python 3中,自定义元类可以定义一个在上面的简化列表中"步骤1" 之前__prepare__运行的函数,这使它可以更好地控制类的主体.具体来说,引用PEP 3115 ...:

__prepare__返回一个类似字典的对象,用于在评估类体时存储类成员定义.换句话说,类主体被评估为一个功能块(就像它现在一样),除了局部变量字典被返回的字典替换__prepare__.该字典对象可以是常规字典或自定义映射类型.

...

一个示例是一个元类,它使用有关成员声明排序的信息来创建C结构.元类将提供一个自定义字典,只需记录插入顺序.

你不想像在这个例子中那样"创建一个C结构",但是字段的顺序是至关重要的(允许使用你想要的位置参数),所以自定义元类(通过base获得model)会有一个__prepare__类方法返回有序字典.这消除了特定的问题,但是,当然,只有当您愿意使用这个"神奇的ORM"将所有代码切换到Python 3.您会是吗?

一旦确定,问题是,您想要执行什么数据库操作,以及如何执行.当然,你的例子根本没有说明这一点.是taskList属性名称特殊,或应任何分配给其他的属性,db对象是"自动保存"(通过名称和,还有什么其他特点[S])和"autoretrieved"在使用?有没有办法删除实体,改变它们,找到它们(除了曾经被列在db对象的同一属性中)?如果需要身份验证,您的示例代码如何知道要使用的数据库服务以及如何对其进行身份验证(例如,通过用户标识和密码)?

您列出的具体任务并不难实现(例如,在Google App Engine的存储服务之上,它不需要身份验证,也不需要指定"使用什么数据库服务"). model的元类会反省类的字段并Model为类生成一个GAE ,该db对象将用于__setattr__设置atexit触发器来存储属性的最终值(Model当然是一个不同类型的实体),并__getattr__获取该属性的从存储中恢复的信息.当然,如果没有一些额外的数据库功能,这一切都将毫无用处;-).

编辑:所以我做了一个小原型(Python 2.6,基于sqlite)并把它放在http://www.aleax.it/lustdb.zip上 - 这是一个包含225行的3K zipfile lustdb.py(太长了,无法发布)这里)两个小的测试文件大致相当于OP的原件:test0.py是......:

from lustdb import *  

class Task(Model): 
    title = ''
    done = False

db.taskList = []    
db.taskList.append(Task(title='Beat old sql interfaces', done=False))
db.taskList.append(Task(title='Illustrate different syntax modes', done=True))

并且test1.p1......:

from lustdb import *

print 'Done tasks:'
for task in db.taskList:
    if task.done:
        print task

运行test0.py(在具有可写/tmp目录的计算机上- 即任何Unix-y操作系统,或者在Windows上,mkdir \tmp以前任何时间运行过的操作系统;-)没有输出; 之后,运行test1.py输出:

Done tasks:
Task(done=True, title=u'Illustrate different syntax modes')

请注意,这些在很多方面都比OP的例子要小得多"疯狂",例如...:

1. no (expletive delete) redundancy whereby `db.taskList` is a synonym of `db['taskList']`, only the sensible former syntax (attribute-access) is supported
2. no mysterious (and totally crazy) way whereby a `done` attribute magically becomes `isDone` instead midway through the code
3. no mysterious (and utterly batty) way whereby a `print task` arbitrarily (or magically?) picks and prints just one of the attributes of the task
4. no weird gyrations and incantations to allow positional-attributes in lieu of named ones (this one the OP agreed to)

当然原型(原型将;-)在许多方面都有很多不足之处(清晰度,文档,单元测试,优化,错误检查和诊断,不同后端之间的可移植性,尤其是除了隐含的那些之外的数据库功能)问题).缺少的数据库功能很多(例如,OP的原始示例无法识别模型的"主键"或任何其他类型的唯一性约束,因此重复数据可能比比皆是;并且只会从那里变得更糟; - ).尽管如此,对于225行(190行空行,评论和文档字符串;-),我的偏见并不是太糟糕.

继续玩这个项目的正确方法当然是lustdb在code.google.com的托管部分(或任何其他良好的开源托管网站上启动一个新的开源项目,包括问题跟踪器,维基,代码评论支持,在线浏览,DVCS支持等等) - 我自己做,但我在code.google.com上可以启动的开源项目数量接近极限,不想"刻录"以这种方式最后一两个;-).

BTW,该lustdb模块的名称是OP的首字母(前后两个字母的首字母和姓氏),在传统awk和朋友的传统- 我认为听起来很好(和大多数其他明显的名称,如simpledbdumbdb被采取;-).


如果我不关心_personally_关于"代码"(以及程序开发的其他方面),为什么我要花我的空闲时间试图帮助这个网站上的人?!无论如何,使属性访问和索引等效(如上所述)绝对不是"用更少的代码编写代码"的任何帮助 - 这只是一个可怕的想法,导致重复和不一致而没有任何好处,我真的不能弄清楚任何声称喜欢Python的人可能会想要任何与语言及其"禅"相反的东西.
推荐阅读
ERIK又
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有