Records 源码阅读与实践

Records 是一个轻量级的Python库,用于简洁高效地执行SQL查询。它支持多种数据库,如RedShift, Postgres, MySQL等。本文介绍了Records的源码阅读,包括Record、RecordCollection、Database和Connection类的功能,以及如何进行数据库连接、查询、事务处理和数据导出等实践操作。" 128780125,11602020,Matplotlib数据可视化:画布分区技巧,"['信息可视化', 'matplotlib', 'python', '数据分析']
摘要由CSDN通过智能技术生成


Records

简介

Records 是用于对大多数关系型数据库进行原始的 SQL 语句查询的第三方库,由 kennethreitz 创建,目前仅 500 多行代码,非常简单但又十分强大。它支持的数据库有 RedShift, Postgres, MySQL, SQLite, Oracle, and MS-SQL

Github:https://github.com/kennethreitz/records

SQL for Humans™ https://pypi.python.org/pypi/records/

主目录 描述
examples 使用示例文件
tests 测试代码文件
.gitgnore 配置 Git 需要忽略的文件
.travis.yml 持续集成工具 Travis CI 的配置文件,用于在代码发生变更时自动运行构建、测试
HISTORY.rst .rst文件是一种纯文本文件,全称reStructuredText,此处为更新记录
LICENSE 开源许可证,records 使用 ISC 许可,功能上与两句版 BSD 许可和 MIT 许可一致
MANIFESR.in 指定需要打包的文件,因为 python 打包程序默认不打包一些文本文档,所以需要在此处指定
Makefile make命令工具,此处定义了一些shell脚本命令用于发布、测试等
Pipfile PipfilePipfile.lock 是 Pipenv 生成依赖管理文件,用于替代过于简陋的 requirements.txt 文件
Pipfile.lock Pipfile.lock 是根据 Pipfile 和当前环境自动生成的 JSON 格式的依赖文件,任何情况下都不要手动修改该文件
README.rst README 文件,关于 Records 简单介绍
records.py Records 源码文件
setup.py 用于 python 包构建工具的代码文件
tox.ini tox是通用的虚拟环境管理和测试命令行工具,此处用于测试records在不同 python 版本的兼容性

records.py

以下是按照源代码顺序进行的阅读记录,如有错误,欢迎指正!

# -*- coding: utf-8 -*-

PEP 0263:建议在Python文件头部声明使用何种编码

import

import os
# 用于处理文件和目录
from sys import stdout
# Python 默认输出
from collections import OrderedDict
# OrderedDict 有序字典,根据元素放入先后顺序排列
from contextlib import contextmanager
# 上下文管理器
from inspect import isclass
# isclass 判断是否为类对象

import tablib
# 将数据输出为常用格式的第三方库
from docopt import docopt
# 解析命令行参数
from sqlalchemy import create_engine, exc, inspect, text
# sqlalchemy 提供 SQL 工具和 ORM 工具

什么是ORM?
全称 Object-Relationl Mapping,在Python中表现为关系型数据库的对象和Python对象之间的映射,有了这个映射,我们就可以直接通过调用Python对象来操作数据库。

isexception 方法

# isexception 判断对象是否为Exception类实例或其子类
def isexception(obj):
    """Given an object, return a boolean indicating whether it is an instance
    or subclass of :py:class:`Exception`.
    """
    if isinstance(obj, Exception):	
        return True
    if isclass(obj) and issubclass(obj, Exception):	
        return True
    return False

Record 类

# Record 储存单行数据的类
class Record(object):
    """A row, from a query, from a database."""
    __slots__ = ('_keys', '_values')	# 限制类的合法属性集(仅对新式类作用)

    def __init__(self, keys, values):
        self._keys = keys	# 单下划线保护变量
        self._values = values

        # Ensure that lengths match properly.
        # assert 断言,表达式返回为False则报错,此处为确保 _keys _values 长度一致
        assert len(self._keys) == len(self._values)
        
	# keys 和 values 都是 getter 方法,是用于获取保护变量值的函数
    def keys(self):
        """Returns the list of column names from the query."""
        return self._keys

    def values(self):
        """Returns the list of values from the query."""
        return self._values
    
	# __repr__ 定义对象在终端返回的字符串形式
    def __repr__(self):
        return '<Record {}>'.format(self.export('json')[1:-1])
	
    # __getitem__ 定义 obj[key] 索引返回值
    def __getitem__(self, key):
        # Support for index-based lookup.
        # 整数索引支持
        if isinstance(key, int):	# 如果 key 为整数类型
            return self.values()[key]

        # Support for string-based lookup.
        # 字符索引支持
        if key in self.keys():	# 如果 key 为 keys属性中的值
            i = self.keys().index(key) # 返回该 key 的位置
            if self.keys().count(key) > 1:	# 如果 key 在 keys 属性中有多值
                raise KeyError("Record contains multiple '{}' fields.".format(key))
            return self.values()[i]	
        
        raise KeyError("Record contains no '{}' field.".format(key))
	
    # __getattr__ 属性查找,定义 obj.key 返回值
    def __getattr__(self, key):
        try:
            return self[key]
        except KeyError as e:
            raise AttributeError(e)
            
	# __dir__ 定义 obj 属性信息,通过 dir(obj) 调用返回
    def __dir__(self):
        standard = dir(super(Record, self))
        # Merge standard attrs with generated ones (from column names).
        return sorted(standard + [str(k) for k in self.keys()])

    # get 实现类似于字典的 get 方法,若找不到值则返回默认值
    def get(self, key, default=None):
        """Returns the value for a given key, or default."""
        try:
            return self[key]
        except KeyError:
            return default
	
    # as_dict 生成字典,ordered 控制是否返回有序字典
    def as_dict(self, ordered=False):
        """Returns the row as a dictionary, as ordered."""
        items = zip(self.keys(), self.values())

        return OrderedDict(items) if ordered else dict(items)
	
    # @property 装饰器,将函数调用方式改为属性调用方式(obj.dataset)
    # dataset 将 keys 和 values 放入 tablib 的 Dataset 对象
    @property
    def dataset(self):
        """A Tablib Dataset containing the row."""
        data = tablib.Dataset()
        data.headers = self.keys()
		
        # _reduce_datetimes 在后面有定义,若 values 为 datetime 类型则转换为字符串
        row = _reduce_datetimes(self.values())
        data.append(row)

        return data
    
	# export 调用Dataset对象的export方法输出指定格式数据
    def export(self, format, **kwargs):
        """Exports the row to the given format."""
        return self.dataset.export(format, **kwargs)

​ Record 对象储存的是单条记录,keys 负责储存列名,values 负责储存每列对应的值,支持通过整数、字符串、get 方法索引,可以通过

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值