kennethreitz-archive/records:
Records: SQL for Humans™.records
是 python
的一个简单的库, 代码量比较少, 用来学习阅读笔记容易懂. 它主要是封装了 SQLAlchemy
和 Tablib
库, 一个用来处理数据库的操作, 一个用来格式化各种导出. 从中我们可以学会如何组合已有的库.
源码阅读
找入口
通过官方的文档示例1
2
3
4import records
db = records.Database('postgres://...')
rows = db.query('select * from active_users') # or db.query_file('sqls/active-users.sql')
从上面可以看出, Database
类是主要的入口类.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15class Database(object):
"""A Database. Encapsulates a url and an SQLAlchemy engine with a pool of
connections.
"""
def __init__(self, db_url=None, **kwargs):
# If no db_url was provided, fallback to $DATABASE_URL.
self.db_url = db_url or os.environ.get('DATABASE_URL')
if not self.db_url:
raise ValueError('You must provide a db_url.')
# Create an engine.
self._engine = create_engine(self.db_url, **kwargs)
self.open = True
主要类的关系
Database
类的数据库操都是操作 Connection
类, 而 Connection
是 SQLAlchemy
的连接封装.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19class Database(object):
...
def get_connection(self):
"""Get a connection to this Database. Connections are retrieved from a
pool.
"""
if not self.open:
raise exc.ResourceClosedError('Database closed.')
return Connection(self._engine.connect())
def query(self, query, fetchall=False, **params):
"""Executes the given SQL query against the Database. Parameters can,
optionally, be provided. Returns a RecordCollection, which can be
iterated over to get result rows as dictionaries.
"""
with self.get_connection() as conn:
return conn.query(query, fetchall, **params)
1 | class Connection(object): |
从源码学使用
因为没有文档, 有些使用需要看源码才会, 比如使用事务1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16class Database(object):
...
def transaction(self):
"""A context manager for executing a transaction on this Database."""
conn = self.get_connection()
tx = conn.transaction()
try:
yield conn
tx.commit()
except:
tx.rollback()
finally:
conn.close()
可以看到返回的是一个支持上下文管理的连接对象
1 | with db.transaction() as tx: |