GINO 基础教程

您所在的位置:网站首页 gino是什么品牌 GINO 基础教程

GINO 基础教程

2024-07-04 05:27| 来源: 网络整理| 查看: 265

GINO 基础教程¶

这是一篇写给刚入坑同学的指南,将介绍 GINO 的基本部分。阅读之前,请先了解以下知识点:

关系型数据库,尤其是 PostgreSQL

Python 异步编程

您不需要对 SQLAlchemy 有所了解。

介绍¶

简单来说,GINO 可以在您的异步应用中帮助您完成 SQL 语句的生成及执行,您只需要通过友好的对象化 API 来操作您的数据即可,无需亲自编写 SQL 与数据库交互。

因为异步编程并不会使您的程序变快——如果说不拖累的话——而且还会增加复杂度和风险,所以也许您并不需要 GINO 或者说是异步数据库连接。跳坑之前请先阅读为什么要用异步 ORM?。

安装¶

请在终端中执行以下命令以安装 GINO:

$ pip install gino

以上就是安装 GINO 的推荐方式,因为这种方式始终会去安装最新的稳定版。

如果您还没有安装过 pip,您可以参阅 Python 安装指南。

另外如果您在使用 Poetry 进行项目依赖关系管理,那需要执行的则是:

$ poetry add gino 声明模型¶

开始之前,我们需要先创建一个 Gino 的全局实例,通常叫做 db:

from gino import Gino db = Gino()

db 可以被当做是数据库的一个代表,后续大部分的数据库交互都将通过它来完成。

“Model” 是 GINO 中的一个基本概念,它表示继承自 db.Model 的用户定义类。每个 Model 的子类代表了数据库中的一张表,而这些类的对象则代表了对应表中的一行数据。如果您曾经使用过其它 ORM 产品,对这种映射关系应该不感到陌生。现在我们尝试定义一个 model:

class User(db.Model): __tablename__ = 'users' id = db.Column(db.Integer(), primary_key=True) nickname = db.Column(db.Unicode(), default='noname')

这里的 User 类其实就是在定义一张叫做 users 的数据库表,包含了 id 和 nickname 两个字段。请注意,__tablename__ 是一个必要的固定属性。GINO 建议使用单数名词来为 model 命名,同时使用复数名词去命名表。每个 db.Column 属性都定义了一个数据库字段,其中第一个参数是字段类型,其余参数则用来定义字段其他属性或约束。您可以参考 SQLAlchemy 的文档来了解不同 db 类型到数据库类型的对应关系。

注解

SQLAlchemy 是 Python 中一个强大的非异步 ORM 库,而 GINO 就是基于其构建的。通过不同的 SQL 方言实现,SQLAlchemy 支持包括 PostgreSQL 和 MySQL 在内的许多流行的 RDBMS,以至于有时相同的 Python 代码可以不经修改地运行在不同的数据库上。GINO 自然也承袭了这一特性,但目前暂仅支持 PostgreSQL(通过 asyncpg)。

如果需要定义涵盖多个列的数据库约束或索引,您仍然可以通过 model 类属性的方式来定义,属性名称虽未被用到,但不能重复。例如:

class Booking(db.Model): __tablename__ = 'bookings' day = db.Column(db.Date) booker = db.Column(db.String) room = db.Column(db.String) _pk = db.PrimaryKeyConstraint('day', 'booker', name='bookings_pkey') _idx1 = db.Index('bookings_idx_day_room', 'day', 'room', unique=True) _idx2 = db.Index('bookings_idx_booker_room', 'booker', 'room')

另外如果有倾向性,您也可以在 model 类之外定义约束和索引,请参考 SQLAlchemy 文档来了解更多细节。

由于一些限制,目前不允许在父类中直接使用类属性的方式来单独定义数据库约束和索引,__table_args__ 也是一样的。GINO 提供了 declared_attr() 来实现比如 mixin 类这样的功能,更多信息请参阅其 API 文档。

建立连接¶

前面的声明只是定义了映射关系,并非实际在数据库中创建了这些表结构。为了使用 GINO 来创建表,我们需要先与数据库建立连接。这里我们先为本指南创建一个 PostgreSQL 的数据库实例:

$ createdb gino

然后,告诉我们的 db 对象去连接这个数据库:

import asyncio async def main(): await db.set_bind('postgresql://localhost/gino') asyncio.get_event_loop().run_until_complete(main())

如果执行成功了,那就意味着您连上了新创建的数据库。此处的 postgresql 代表了要用的数据库方言(默认的驱动是 asyncpg,您也可以显式地指定使用它:postgresql+asyncpg:// 或者就只写 asyncpg://),localhost 是数据库服务器所在的地址,gino 是数据库实例的名字。这里可以读到更多关于如何构造一个数据库 URL 的信息。

注解

在底层,set_bind() 调用了 create_engine() 来创建 engine,并将其绑定到 db 对象上。GINO engine 与 SQLAlchemy engine 类似,但 GINO engine 是异步的,而后者是阻塞式的。关于如何使用 engine,请参考 GINO 的 API 文档。

建立连接之后,我们就可以用 GINO 在数据库中创建我们的表了(在同一个 main() 函数里):

await db.gino.create_all()

警告

这里是 db.gino.create_all,而不是 db.create_all,因为 db 继承自 SQLAlchemy 的 MetaData,而 db.create_all 是 SQLAlchemy 的阻塞式方法,无法适用于绑定的 GINO engine。

实践中 create_all() 通常并不是一个理想的解决方案。为了管理数据库表结构,我们通常推荐使用诸如 Alembic 这样的工具,请参阅如何 使用 Alembic。

如果您想显式地断开与数据库的连接,您可以这么做:

await db.pop_bind().close()

继续之前,让我们重新看一下前面所有的代码:

import asyncio from gino import Gino db = Gino() class User(db.Model): __tablename__ = 'users' id = db.Column(db.Integer(), primary_key=True) nickname = db.Column(db.Unicode(), default='noname') async def main(): await db.set_bind('postgresql://localhost/gino') await db.gino.create_all() # further code goes here await db.pop_bind().close() asyncio.get_event_loop().run_until_complete(main()) 增删改查¶

为了操作数据库中的数据,GINO 提供了基本的基于对象的增删改查功能。

增¶

让我们从创建一个 User 对象开始:

user = await User.create(nickname='fantix') # This will cause GINO to execute this SQL with parameter 'fantix': # INSERT INTO users (nickname) VALUES ($1) RETURNING users.id, users.nickname

正如之前所说,user 对象代表了数据库中新插入的这一行数据。您可以通过 user 对象上的之前定义的列属性来访问每一列的值:

print(f'ID: {user.id}') # 1 print(f'Nickname: {user.nickname}') # fantix

另外,您也可以先在内存中创建一个 user 对象,然后再将其插入到数据库中:

user = User(nickname='fantix') user.nickname += ' (founder)' await user.create() 查¶

想要通过主键来获取一个 model 对象,您可以使用 model 的类方法 get()。比如,重新获取刚才插入的同一行数据:

user = await User.get(1) # SQL (parameter: 1): # SELECT users.id, users.nickname FROM users WHERE users.id = $1

常规的 SQL 查询则是通过类属性 query 来完成。比如,获取数据库中所有的 User 对象的列表:

all_users = await db.all(User.query) # SQL: # SELECT users.id, users.nickname FROM users

或者,您也可以使用 query 的 gino 扩展。比如,下面的代码可以实现一样的效果:

all_users = await User.query.gino.all() # SQL: # SELECT users.id, users.nickname FROM users

注解

实际上,User.query 是一个普通的 SQLAlchemy 查询对象,SQLAlchemy 的阻塞式执行方法依然存在其上,因此 GINO 向所有 SQLAlchemy 的“Executable”对象注入了一个 gino 扩展,以便在不影响 SQLAlchemy 原有 API 的基础上,让直接异步地执行这些查询对象更容易,而不用每次都通过 engine 或 db 对象来执行。

现在让我们尝试增加一些过滤器。比如,查找出所有 ID 小于 10 的用户:

founding_users = await User.query.where(User.id $1

有了基本的 增删改查,您应该已经可以用 GINO 做出一些不可思议的东西来了。这篇上手指南到此结束,要了解更多请继续阅读文档的剩余部分。祝编程愉快!



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3