<jupyter_start><jupyter_text>>官方教程：https://python-gino.org/docs/zh/master/tutorials/tutorial.html 介绍 [¶](introduction "永久链接至标题")简单来说，GINO 可以在您的异步应用中帮助您完成 SQL 语句的生成及执行，您只需要通过友好的对象化 API 来操作您的数据即可，无需亲自编写 SQL 与数据库交互。因为异步编程并不会使您的程序变快——如果说不拖累的话——而且还会增加复杂度和风险，所以也许您并不需要 GINO 或者说是异步数据库连接。跳坑之前请先阅读[为什么要用异步 ORM？](https://python-gino.org/docs/zh/master/explanation/why.html)。这是一篇写给刚入坑同学的指南，将介绍 GINO 的基本部分。阅读之前，请先了解以下知识点：*   关系型数据库，尤其是 [PostgreSQL](https://www.postgresql.org/)    *   [Python 异步编程](https://realpython.com/async-io-python/)    您不需要对 [SQLAlchemy](https://www.sqlalchemy.org/) 有所了解。  安装>pip install gino 使用 声明模型 [¶](declare-models "永久链接至标题")开始之前，我们需要先创建一个 [`Gino`](https://python-gino.org/docs/zh/master/reference/api/gino.api.htmlgino.api.Gino "gino.api.Gino") 的全局实例，通常叫做 `db`：<jupyter_code>from gino import Gino

db = Gino()<jupyter_output><empty_output><jupyter_text>`db` 可以被当做是数据库的一个代表，后续大部分的数据库交互都将通过它来完成。“Model” 是 GINO 中的一个基本概念，它表示继承自 [`db.Model`](https://python-gino.org/docs/zh/master/reference/api/gino.api.htmlgino.api.Gino.Model "gino.api.Gino.Model") 的用户定义类。**每个 [`Model`](https://python-gino.org/docs/zh/master/reference/api/gino.declarative.htmlgino.declarative.Model "gino.declarative.Model") 的子类代表了数据库中的一张表，**而这些类的对象则代表了对应表中的一行数据。如果您曾经使用过其它 ORM 产品，对这种映射关系应该不感到陌生。现在我们尝试定义一个 model：<jupyter_code>class User(db.Model):
    __tablename__ = 'users'

    id = db.Column(db.Integer(), primary_key=True)
    nickname = db.Column(db.Unicode(), default='<PASSWORD>')<jupyter_output><empty_output><jupyter_text>这里的 `User` 类其实就是在定义一张叫做 `users` 的数据库表，包含了 `id` 和 `nickname` 两个字段。请注意，**`__tablename__` 是一个必要的固定属性**。GINO 建议使用**单数名词来为 model 命名**，同时使用**复数名词去命名表**。每个 [`db.Column`](https://docs.sqlalchemy.org/en/13/core/metadata.htmlsqlalchemy.schema.Column "(在 SQLAlchemy v1.3)") 属性都定义了一个数据库字段，其中第一个参数是字段类型，其余参数则用来定义字段其他属性或约束。您可以参考 [SQLAlchemy](http://docs.sqlalchemy.org/en/latest/core/type_basics.html) 的文档来了解不同 `db` 类型到数据库类型的对应关系。>注解:  [SQLAlchemy](https://www.sqlalchemy.org/) 是 Python 中一个强大的非异步 ORM 库，而 GINO 就是基于其构建的。通过不同的 SQL 方言实现，SQLAlchemy 支持包括 PostgreSQL 和 MySQL 在内的许多流行的 RDBMS，以至于有时相同的 Python 代码可以不经修改地运行在不同的数据库上。GINO 自然也承袭了这一特性，**但目前暂仅支持 PostgreSQL**（通过 [asyncpg](https://github.com/MagicStack/asyncpg)）。如果需要定义涵盖多个列的数据库约束或索引，您仍然可以通过 model 类属性的方式来定义，属性名称虽未被用到，但不能重复。例如：<jupyter_code>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')<jupyter_output><empty_output><jupyter_text>另外如果有倾向性，您也可以在 model 类之外定义约束和索引，请参考 [SQLAlchemy 文档](http://docs.sqlalchemy.org/en/latest/core/constraints.html)来了解更多细节。由于一些限制，目前不允许在父类中直接使用类属性的方式来单独定义数据库约束和索引，`__table_args__` 也是一样的。GINO 提供了 [`declared_attr()`](https://python-gino.org/docs/zh/master/reference/api/gino.declarative.htmlgino.declarative.declared_attr "gino.declarative.declared_attr") 来实现比如 mixin 类这样的功能，更多信息请参阅其 API 文档。  建立连接 [¶](get-connected "永久链接至标题")前面的声明只是定义了映射关系，并非实际在数据库中创建了这些表结构。为了使用 GINO 来创建表，我们需要先与数据库建立连接。这里我们先为本指南创建一个 PostgreSQL 的数据库实例：然后，告诉我们的 `db` 对象去连接这个数据库：<jupyter_code>import asyncio

async def main():
    await db.set_bind('postgresql://postgre:xxxx@47.102.127.xxx:5432/gino')

asyncio.get_event_loop().run_until_complete(main())<jupyter_output><empty_output><jupyter_text>如果执行成功了，那就意味着您连上了新创建的数据库。此处的 `postgresql` 代表了要用的数据库方言（默认的驱动是 `asyncpg`，您也可以显式地指定使用它：`postgresql+asyncpg://` 或者就只写 `asyncpg://`），`localhost` 是数据库服务器所在的地址，`gino` 是数据库实例的名字。[这里](https://docs.sqlalchemy.org/en/latest/core/engines.html)可以读到更多关于如何构造一个数据库 URL 的信息。>注解:  在底层，[`set_bind()`](https://python-gino.org/docs/zh/master/reference/api/gino.api.htmlgino.api.Gino.set_bind "gino.api.Gino.set_bind") 调用了 [`create_engine()`](https://python-gino.org/docs/zh/master/reference/api/gino.htmlgino.create_engine "gino.create_engine") 来创建 engine，并将其绑定到 `db` 对象上。GINO engine 与 SQLAlchemy engine 类似，但 GINO engine 是异步的，而后者是阻塞式的。关于如何使用 engine，请参考 GINO 的 API 文档。建立连接之后，我们就可以用 GINO 在数据库中创建我们的表了（在同一个 `main()` 函数里）：```pyawait db.gino.create_all()```>警告  这里是 `db.gino.create_all`，而不是 `db.create_all`，因为 db 继承自 SQLAlchemy 的 MetaData，而 `db.create_all` 是 SQLAlchemy 的阻塞式方法，无法适用于绑定的 GINO engine。>实践中 `create_all()` 通常并不是一个理想的解决方案。为了管理数据库表结构，我们通常推荐使用诸如 Alembic 这样的工具，请参阅如何 使用 [Alembic](https://python-gino.org/docs/zh/master/how-to/alembic.html)。如果您想显式地断开与数据库的连接，您可以这么做：```pyawait db.pop_bind().close()```继续之前，让我们重新看一下前面所有的代码：<jupyter_code>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())<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.15496031746031746, 'fraction_numerical': 0.0035714285714285713, 'mean_word_length': 7.2234910277324635, 'pattern_counts': {'":': 0, '<': 22, '<?xml version=': 0, '>': 28, 'https://': 16, 'lorem ipsum': 0, 'www.': 3, 'xml': 0}, 'pii_count': 1, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '223023', 'license': 'MIT', 'n_tokens_mistral': 2771, 'n_tokens_neox': 2947, 'n_words': 244, 'path': 'ORM/GINO/GINO基础教程.ipynb', 'repo_name': 'wanZzz6/Modules-Learn', 'size': '5036'}