Skip to main content

lightweight SQLAlchemy based ORM

Project description

<pre>
/\ \ /\__\ ___ /\__\ /\ \
\:\ \ /:/ / /\ \ /::| | /::\ \
\:\ \ /:/__/ \:\ \ /:|:| | /:/\:\ \
/::\ \ /::\ \ ___ /::\__\ /:/|:| |__ /:/ \:\ \
/:/\:\__\ /:/\:\ /\__\ __/:/\/__/ /:/ |:| /\__\ /:/__/_\:\__\
/:/ \/__/ \/__\:\/:/ / /\/:/ / \/__|:|/:/ / \:\ /\ \/__/
/:/ / \::/ / \::/__/ |:/:/ / \:\ \:\__\
\/__/ /:/ / \:\__\ |::/ / \:\/:/ /
/:/ / \/__/ /:/ / \::/ /
\/__/ \/__/ \/__/

</pre>

# Thing 是什么?

Thing是一个基于SQLAlchemy的配置简单、使用简单且灵活的ORM。

# 使用方法

举个简单的例子,假如有3个表:comment, post, user, 3个表的字段分别是:

comment表:
```
+---------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+------------------+------+-----+---------+----------------+
| id | int(11) unsigned | NO | PRI | NULL | auto_increment |
| user_id | int(11) | YES | MUL | NULL | |
| post_id | int(11) | YES | MUL | NULL | |
| content | text | YES | | NULL | |
+---------+------------------+------+-----+---------+----------------+
```

post表:
```
+---------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+------------------+------+-----+---------+----------------+
| id | int(11) unsigned | NO | PRI | NULL | auto_increment |
| user_id | int(11) | YES | MUL | NULL | |
| created | int(11) | YES | | NULL | |
| content | text | YES | | NULL | |
| title | varchar(255) | YES | | NULL | |
+---------+------------------+------+-----+---------+----------------+
```

user表:
```
+-------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+------------------+------+-----+---------+----------------+
| id | int(11) unsigned | NO | PRI | NULL | auto_increment |
| name | varchar(30) | YES | | NULL | |
+-------+------------------+------+-----+---------+----------------+
```

## 定义Model

先来看看目录结构
```
├── __init.py__
├── conn.py # 用于数据库连接
├── models
│   ├── __init__.py
│   ├── comment.py
│   ├── post.py
│   ├── user.py
└── test.py
```
test.py就是进行测试的地方,先来看看各个model的内容:

### comment.py

```
import thing

class Comment(thing.Thing):
_belongs_to = {
'post': {
'model': 'models.post.Post',
'foreign_key': 'post_id',
},
'author': {
'model': 'models.user.User',
'foreign_key': 'user_id',
},
}
```

### post.py

```
import thing

class Post(thing.Thing):
_belongs_to = {
'author': {
'model': 'models.user.User',
'foreign_key': 'user_id',
}
}
_has_many = {
'comments': {
'model': 'models.comment.Comment',
'foreign_key': 'user_id',
}
}
```

### user.py

```
import thing

class User(thing.Thing):
_has_many = {
'posts': {
'model': 'models.post.Post',
'foreign_key': 'user_id'
},
'comments': {
'model': 'models.comment.Comment',
'foreign_key': 'user_id'
}
}
```

再来看看conn.py

### conn.py

```
import thing

config = {
'db': {
'master': {
'url': 'mysql://root:123456@127.0.0.1:3306/test?charset=utf8',
'echo': False,
},
'slave': {
'url': 'mysql://root:123456@127.0.0.1:3306/test?charset=utf8',
'echo': False,
},
},
'redis': {
'host': 'localhost',
'port': 6379,
'db': 1,
},
'thing': {
'debug': True,
}
}

thing.Thing.config(config)
```

OK,万事具备,开工!

```
import conn
from models.comment import Comment
from models.user import User
from models.post import Post

# -------- 插入数据 --------
user = User()
user.name = 'foo'
user.save()
# 或者 user = User(name='foo').save()

# -------- 获取数据 --------
user = User().find(1)
print user.name

# -------- 获取关联数据 -------
posts = User().find(1).posts.findall()
# 如果要设置offset / limit, 在findall里加入参数即可
# posts = User().find(1).posts.findall(offset = 0, limit = 20)

# ------- 删除数据 -------
User().find(1).delete()

# ------- 更新数据 -------
user = User().find(1)
user.name = 'bar'
user.save()
```

# 动态查询

这个是受Rails影响,觉得很方便就拿来了。比如 `Post().count_by_user_id(3)`,就可以找到user_id为3的用户发表的文章数量。要获取`user_id`为3的用户发表的文章,可以`Post().findall_by_user_id(3, limit=20)`,比起`Post().where('user_id', '=', 3).findall()`更加简洁和明了。

# 关于性能和缓存

Thing内置了Redis作为缓存,你甚至都不需要知道Redis的存在,正常该怎么用还怎么用,Thing会自动处理缓存的生成、读取、过期、删除等操作。

假设表posts里有5条数据,在获取每条post后,还想获取该post对应的用户信息,代码如下:

```
posts = Post().findall(limit=5)

for post in posts:
print post.author
```

在开启Debug的情况下,可以在终端看到如下显示:

```
DEBUG - [cost:0.0032] - SELECT post.id, post.user_id, post.created, post.content, post.title
FROM post ORDER BY post.id DESC
LIMIT -1 OFFSET :param_1
DEBUG - Cache Read: thing.User:1
{u'id': 1, u'name': u'lzyy'}
DEBUG - Cache Read: thing.User:1
{u'id': 1, u'name': u'lzyy'}
DEBUG - Cache Read: thing.User:1
{u'id': 1, u'name': u'lzyy'}
DEBUG - Cache Read: thing.User:1
{u'id': 1, u'name': u'lzyy'}
DEBUG - Cache Read: thing.User:1
{u'id': 1, u'name': u'lzyy'}
```

可以看到用户的信息都是从缓存中读取的,所以不用担心n+1的问题。
假如用户的信息被更新,缓存也会自动更新。

# 其他

* 配置信息里的`master`和`slave`为必选项,可以相同。Thing会根据不同的查询,自动找到对应的db。如find/findall会找slave,update/delete会找master。
* 配置信息里的redis项为必选项。
* 动态查询目前支持`find_by`, `findall_by`, `findall_in`, `count_by`
* 内置了8个钩子,会在相应的事件发生时被调用,分别是:`_before_insert`,`_after_insert`,`_before_update`,`_after_update`,`_before_delete`,`_after_delete`,`_before_find`,`_after_find`,可以在子类里覆盖这些方法来实现自己的逻辑。
* 复杂的SQL可以使用`execute`方法,返回的结果是SQLAlchemy的ResultProxy
* 如果要一次更新多处的话,可以使用`updateall`方法,`Post().where('user_id', '=', 1).updateall(user_id=2)`
* 表名如果和小写的类名不一样的话,可以在子类里重新设置`_tablename`
* 每个表一定要有主键,默认为`id`,可以在子类里重新设置`_primary_key`
* 支持has_many和belongs_to,可以在子类里定义`_has_many`和`_belongs_to`
* 没有`join`方法

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

thing-0.3.1.tar.gz (10.7 kB view details)

Uploaded Source

Built Distribution

thing-0.3.1.macosx-10.8-intel.exe (78.8 kB view details)

Uploaded Source

File details

Details for the file thing-0.3.1.tar.gz.

File metadata

  • Download URL: thing-0.3.1.tar.gz
  • Upload date:
  • Size: 10.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for thing-0.3.1.tar.gz
Algorithm Hash digest
SHA256 b82365025f1744ce3ee5e3ef5717c9c4938708040843fd5ab0beadf602549632
MD5 17e246e3f6ef1f702a25487d1c5059f4
BLAKE2b-256 7a03b17d3c1043aaa30c50d4fec71085db2d93580580acdd6ccbfc0bfafde1f1

See more details on using hashes here.

File details

Details for the file thing-0.3.1.macosx-10.8-intel.exe.

File metadata

File hashes

Hashes for thing-0.3.1.macosx-10.8-intel.exe
Algorithm Hash digest
SHA256 ad4e2f73f293121b9439ec441c9e07002227dafbd7a8df992ca7f3bb7afc8ee7
MD5 80372b4e93585a0b540ecdf068805d03
BLAKE2b-256 dffac84acec61a74b3d369dfeb09e95f38a14e2cf3555b5fcf1df5b1bf9fb66c

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page