Day 4 - 编写Model

有了ORM,我们就可以把Web App需要的3个表用Model表示出来:

  1. import time, uuid
  2. from transwarp.db import next_id
  3. from transwarp.orm import Model, StringField, BooleanField, FloatField, TextField
  4. class User(Model):
  5. __table__ = 'users'
  6. id = StringField(primary_key=True, default=next_id, ddl='varchar(50)')
  7. email = StringField(updatable=False, ddl='varchar(50)')
  8. password = StringField(ddl='varchar(50)')
  9. admin = BooleanField()
  10. name = StringField(ddl='varchar(50)')
  11. image = StringField(ddl='varchar(500)')
  12. created_at = FloatField(updatable=False, default=time.time)
  13. class Blog(Model):
  14. __table__ = 'blogs'
  15. id = StringField(primary_key=True, default=next_id, ddl='varchar(50)')
  16. user_id = StringField(updatable=False, ddl='varchar(50)')
  17. user_name = StringField(ddl='varchar(50)')
  18. user_image = StringField(ddl='varchar(500)')
  19. name = StringField(ddl='varchar(50)')
  20. summary = StringField(ddl='varchar(200)')
  21. content = TextField()
  22. created_at = FloatField(updatable=False, default=time.time)
  23. class Comment(Model):
  24. __table__ = 'comments'
  25. id = StringField(primary_key=True, default=next_id, ddl='varchar(50)')
  26. blog_id = StringField(updatable=False, ddl='varchar(50)')
  27. user_id = StringField(updatable=False, ddl='varchar(50)')
  28. user_name = StringField(ddl='varchar(50)')
  29. user_image = StringField(ddl='varchar(500)')
  30. content = TextField()
  31. created_at = FloatField(updatable=False, default=time.time)

在编写ORM时,给一个Field增加一个default参数可以让ORM自己填入缺省值,非常方便。并且,缺省值可以作为函数对象传入,在调用insert()时自动计算。

例如,主键id的缺省值是函数next_id,创建时间created_at的缺省值是函数time.time,可以自动设置当前日期和时间。

日期和时间用float类型存储在数据库中,而不是datetime类型,这么做的好处是不必关心数据库的时区以及时区转换问题,排序非常简单,显示的时候,只需要做一个floatstr的转换,也非常容易。

初始化数据库表

如果表的数量很少,可以手写创建表的SQL脚本:

  1. -- schema.sql
  2. drop database if exists awesome;
  3. create database awesome;
  4. use awesome;
  5. grant select, insert, update, delete on awesome.* to 'www-data'@'localhost' identified by 'www-data';
  6. create table users (
  7. `id` varchar(50) not null,
  8. `email` varchar(50) not null,
  9. `password` varchar(50) not null,
  10. `admin` bool not null,
  11. `name` varchar(50) not null,
  12. `image` varchar(500) not null,
  13. `created_at` real not null,
  14. unique key `idx_email` (`email`),
  15. key `idx_created_at` (`created_at`),
  16. primary key (`id`)
  17. ) engine=innodb default charset=utf8;
  18. create table blogs (
  19. `id` varchar(50) not null,
  20. `user_id` varchar(50) not null,
  21. `user_name` varchar(50) not null,
  22. `user_image` varchar(500) not null,
  23. `name` varchar(50) not null,
  24. `summary` varchar(200) not null,
  25. `content` mediumtext not null,
  26. `created_at` real not null,
  27. key `idx_created_at` (`created_at`),
  28. primary key (`id`)
  29. ) engine=innodb default charset=utf8;
  30. create table comments (
  31. `id` varchar(50) not null,
  32. `blog_id` varchar(50) not null,
  33. `user_id` varchar(50) not null,
  34. `user_name` varchar(50) not null,
  35. `user_image` varchar(500) not null,
  36. `content` mediumtext not null,
  37. `created_at` real not null,
  38. key `idx_created_at` (`created_at`),
  39. primary key (`id`)
  40. ) engine=innodb default charset=utf8;

如果表的数量很多,可以从Model对象直接通过脚本自动生成SQL脚本,使用更简单。

把SQL脚本放到MySQL命令行里执行:

  1. $ mysql -u root -p < schema.sql

我们就完成了数据库表的初始化。

编写数据访问代码

接下来,就可以真正开始编写代码操作对象了。比如,对于User对象,我们就可以做如下操作:

  1. # test_db.py
  2. from models import User, Blog, Comment
  3. from transwarp import db
  4. db.create_engine(user='www-data', password='www-data', database='awesome')
  5. u = User(name='Test', email='test@example.com', password='1234567890', image='about:blank')
  6. u.insert()
  7. print 'new user id:', u.id
  8. u1 = User.find_first('where email=?', 'test@example.com')
  9. print 'find user\'s name:', u1.name
  10. u1.delete()
  11. u2 = User.find_first('where email=?', 'test@example.com')
  12. print 'find user:', u2

可以在MySQL客户端命令行查询,看看数据是不是正常存储到MySQL里面了。

原文: https://wizardforcel.gitbooks.io/liaoxuefeng/content/py2/98.html