每天开心一点

peewee 一个轻量级的ORM

2017-12-30 16:26:00    六月    1484    来源: http://blog.csdn.net/gausszh/article/details/8033615

peewee是一个轻量级的ORM,sf、github上都有。用的是大名鼎鼎的sqlalchemy内核,做了一个简单的包装,用纯python编写,显得十分轻便。

废话不多说,上 直接sudo pip install peewee即可。

[python] view plain copy
  1. from  peewee  import  *  
  2.   
  3. db = SqliteDatabase( 'test.db' ) #peewee.SqliteDatabase   
  4.   
  5. # create a base model class that our application's models will extend,这样我们后面的blog与entry就链接的是同一个数据库了。这个是从django借鉴来的   
  6. class  BaseModel(Model):  
  7.      class  Meta:  
  8.         database = db  
  9.   
  10.   
  11. class  Blog(BaseModel): #创建表,Blog:表名,name:字段,CharField:字段类型,其实就是varchar。peewee.CharField   
  12.     name = CharField()  # <-- VARCHAR   
  13.   
  14.   
  15. class  Entry(BaseModel):  
  16.     headline = CharField()  
  17.     content = TextField()  # <-- TEXT   
  18.     pub_date = DateTimeField()  # <-- DATETIME   
  19.     blog = ForeignKeyField(Blog)  # <-- INTEGER referencing the Blog table   

创建表

          #建立连接 
          db
          .
          connect
          () 
          # 建立表 
          Blog
          .
          create_table
          () 
          Entry
          .
          create_table
          () 

注意:严格来说,不是一定要connect()的,但这是一个好习惯

创建模型实例(实例化)

在我们的交互式脚本编辑器那试试吧,这样能立即看出效果

  1. Use the Model.create() classmethod:

    [python] view plain copy
    1. >>> blog = Blog.create(name= 'Funny pictures of animals blog' )  
    2. >>> entry = Entry.create(  
    3. ...     headline= 'maru the kitty' ,  
    4. ...     content= 'http://www.youtube.com/watch?v=xdhLQCYQ-nQ' ,  
    5. ...     pub_date=datetime.datetime.now(),  
    6. ...     blog=blog  
    7. ... )  
    8.   
    9. >>> entry.blog.name  
    10. 'Funny pictures of animals blog'   
  2. 或者是仿照编程语言的方式进行实例化:

    [python] view plain copy
    1. >>> blog = Blog() #blog就是我们实例化的对象,而Blog就是刚才声明的class   
    2. >>> blog.name =  'Another sweet blog'   
    3. >>> blog.save()  

Traversing foriegn keys通过外键访问

比如我们上面那个例子

[python] view plain copy
  1. >>> entry.blog.name  
  2. 'Funny pictures of animals blog'   

还可以逆转过来 :

[python] view plain copy
  1. >>>  for  entry  in  blog.entry_set: #这个entry_set没太搞懂   
  2. ...      print  entry.headline  
  3. ...  
  4. maru the kitty  

在我们这个peewee引擎中,entry_set是一个 SelectQuery:

  >>> 
  blog
  .
  entry_set 
  <peewee.SelectQuery object at 0x151f510> 
  >>> 
  blog
  .
  entry_set
  .
  sql
  () 
  ('SELECT * FROM entry WHERE blog_id = ?', [1]) 

Model options

还可用多几个数据库

from 
peewee 
import 
* 
custom_db 
= 
SqliteDatabase
(
'custom.db'
) 
class 
CustomModel
(
Model#这种元类 
class 
Meta
: 
database 
= 
custom_db 
):

meta是给引擎提示。引擎要执行一个sql语句的时候,要在那个数据库上执行呢,那就找到这个表所在的class继承的是那个元类

Note

Meta类中除了定义database之外还有其他几个属性。如下

  • database: 确定要用那个库

  • db_table: the name of the database table this model maps to,映射到哪张表

  • indexes: 一个索引的列表

  • ordering: a sequence of columns to use as the default ordering for this model

  • pk_sequence: 主键的名称队列(如果后端支持这种列表的话,peewee 可能会自动创建主键).

下面举一些例子

Specifying indexes:

class 
Transaction
(
Model
): 
from_acct 
= 
CharField
() 
to_acct 
= 
CharField
() 
amount 
= 
DecimalField
() 
date 
= 
DateTimeField
() 
class 
Meta
: 
indexes 
= 
( 
# create a unique on from/to/date 
((
'from_acct'
, 
'to_acct'
, 
'date'
), 
True
),#索引,True的话,索引唯一,False则不唯一 
# create a non-unique on from/to 
((
'from_acct'
, 
'to_acct'
), 
False
), 
) 

Example of ordering:

class 
Entry
(
Model
): 
title 
= 
CharField
() 
body 
= 
TextField
() 
created 
= 
DateTimeField
() 
class 
Meta
: 
# order by created date descending, then title ascending 
ordering 
= 
((
'created'
, 
'desc'
), 
'title'
) 

Model methods对数据表操作的方法

class Modelsave( [ force_insert=False ])到底是save还是creating还是updating,这取决于这个表有木有主键。倘若force_insert设置为True,顾名思义,无论如何都会进行插入操作

example:

[python] view plain copy
  1. >>> some_obj.title =  'new title'   # <-- does not touch the database   
  2. >>> some_obj.save()  # <-- 数据持久化   
classmethod create( **attributes)
Parameters: attributes – 键值对

Create an instance of the Modelwith the given attributes set.

example:

[python] view plain copy
  1. >>> user = User.create(username= 'admin' , password= 'test' )  
delete_instance( [ recursive=False ])

删除我们指定的例子。 如果外键设置成级连的,也会被删除. For more programmatic control,you can call with recursive=True, which will delete any non-nullablerelated models (those that are nullable will be set to NULL).

example:

[python] view plain copy
  1. >>> some_obj.delete_instance()  # <-- it is gone forever   

classmethod filter( *args, **kwargs)#过滤操作,
Parameters:
  • args – a list of Qor Nodeobjects
  • kwargs – a mapping of column + lookup to value, e.g. “age__gt=55”
Return type:

SelectQuery with appropriate WHEREclauses

这是一个很像django的方法. 在 filter() and SelectQuery.where()二者之中的区别就是 filter() 支持链式过滤

>>> 
sq 
= 
Entry
.
filter
(
blog__title
=
'Some Blog'
) 

This method is chainable:

[python] view plain copy
  1. >>> base_q = User.filter(active= True )  
  2. >>> some_user = base_q.filter(username= 'charlie' )  
classmethod get( *args, **kwargs)
Parameters:
  • args – a list of Qor Nodeobjects
  • kwargs – a mapping of column + lookup to value, e.g. “age__gt=55”
Return type

返回实力或者一个Does Not Exist异常

这个很是类型thinkphp中的find与findall,get就是只返回一条。

[python] view plain copy
  1. >>> user = User.get(username=username, password=password  
[python] view plain copy
  1. >>> active = User.select().where(active= True )  
  2. >>>  try :  
  3. ...     user = active.get(username=username, password=password)  
  4. ...  except  User.DoesNotExist:  
  5. ...     user =  None   
classmethodget_or_create( **attributes)
Parameters: attributes –键值对
Return type: 查询结果实例

返回以键值对做查询条件的结果,如果查询不到,就以该键值对创建一个实例

example:

[python] view plain copy
  1. >>> CachedObj.get_or_create(key=key, val=some_val)  
classmethod select( query=None)
Return type: a SelectQuery for the given Model查询结果

example:

[python] view plain copy
  1. >>> User.select().where(active= True ).order_by( 'username' )  
classmethod update( **query)
Return type: an UpdateQuery for the given Model更新

example:

[python] view plain copy
  1. >>> q = User.update(active= False ).where(registration_expired= True )  
  2. >>> q.sql()  
  3. ( 'UPDATE user SET active=? WHERE registration_expired = ?' , [ 0 1 ])  
  4. >>> q.execute()  # <-- execute it   
classmethod delete( **query)
Return type: a DeleteQuery for the given Model删除

example:

[python] view plain copy
  1. >>> q = User.delete().where(active= False )  
  2. >>> q.sql()  
  3. ( 'DELETE FROM user WHERE active = ?' , [ 0 ])  
  4. >>> q.execute()  # <-- execute it   
delelte语句的时候一定要有where语句。
classmethod insert( **query)
Return type: an InsertQuery for the given Model插入

example:

[python] view plain copy
  1. >>> q = User.insert(username= 'admin' , active= True , registration_expired= False )  
  2. >>> q.sql()  
  3. ( 'INSERT INTO user (username,active,registration_expired) VALUES (?,?,?)' , [ 'admin' 1 0 ])  
  4. >>> q.execute()  
  5. 1   
classmethod raw( sql, *params)
Return type: a RawQuery for the given Model使用原始的sql语句

example:

[python] view plain copy
  1. >>> q = User.raw( 'select id, username from users' )  
  2. >>>  for  user  in  q:  
  3. ...      print  user.id, user.username  
classmethodcreate_table( [ fail_silently=False ])
Parameters: fail_silently 如果这个值被设置为True,那么该方法就会在创建的时候先检查一个这个表的存在型.

Create the table for the given model.创建表

example:

>>> 
database
.
connect
() 
>>> 
SomeModel
.
create_table
() 
# <-- creates the table for SomeModel 
classmethod drop_table( [ fail_silently=False ])
Parameters: fail_silently –如果是True,在删除之前会检查该表是否存在.

注意,有外键连接的不会受此影响。

classmethodtable_exists()
Return type: 返回该数据库是否存在,返回bool值