DataType
SQLAlchemy 为数据库中最常见的数据类型进行了抽象,他们都使用 Python 类来表示,所有这些代表数据类型的类都派生自TypeEngine 基类。
SQLAlchemy 中的数据类型分为两种形式:
- CamelCase 类型: 他们是 TypeEngine 的直接子类,该类型在最大程度上对数据库的类型进行了抽象,这意味着他们是与数据库无关的。SQLAlchemy 支持的数据库都可以使用这种类型来定义。例如 String 对应了数据库后端的 VARCHAR 数据类型。还有像 Boolean 尽管并不是所有的数据库都支持该类型,即使支持他们后端的表现也会有区别,但是 SQLAlchemy 屏蔽了他们的区别我们直接就可以使用,并且能够正确处理 Python 到数据库后端类型的转换
- UPPERCASE 类型: 他们是特定 CamelCase 数据类型的子类。他们总是代表一个精确的类型,并且是不可移植的。比较典型的就是 PostgreSQL 的 JSONB、SQL Server 的 IMAGE 和 MYSQL 的 TINYTEXT
CamelCase
SQLAlchemy 为大多数常见的数据类型提供了抽象,他们使用驼峰表示所以被称为 CamelCase 类型,这些数据类型能够在所有支持的数据库中安全迁移:
Python
from sqlalchemy import MetaData
from sqlalchemy import Table, Column, Integer, String
metadata_obj = MetaData()
user = Table(
"user",
metadata_obj,
Column("user_name", String, primary_key=True),
Column("email_address", String(60)),
)
常见 CamelCase 类型
| 类型对象 | 说明 |
|---|---|
| Integer | 整数 |
| SmallInteger | 较小的整数 |
| BigInteger | 大整数 |
| Float | 浮点数 |
| Double | 双精度浮点数 |
| Numeric | 数值(非整数) |
| Boolean | 布尔类型 |
| Date | 日期 |
| Time | 时间 |
| DateTime | 日期时间 |
| Interval | 时间间隔 |
| LargeBinary | 大型二进制类型 |
| PickleType | Python 序列化对象(特殊的二进制) |
| String | 定长字符串,允许String(size) |
| Text | 可变大小字符串 |
| Unicode | 可变长度的 Unicode 字符串 |
| Enum | 枚举 |
| Uuid | UUID |
Tips
CamelCase 可以看作是通用的类型,他自动在 Python <=> 特定数据库 间交换数据而不需要用户关系内部的细节。同时他们在构建 CREATE TABLE 语句是会自动替换为后端的支持的数据类型,用户不需要关心其中的细节。
UPPERCASE
全大写的数据类型形式表示特定于某个后端,他们都位于 sqlalchemy.dialects.xxx 命名空间中:
| 类型名 | 描述 |
|---|---|
| ARRAY | PostgreSQL 中 ARRAY |
| BIGINT | - |
| BINARY | - |
| BLOB | - |
| BOOLEAN | - |
| CHAR | - |
| CLOB | - |
| DATE | - |
| DATETIME | - |
| DECIMAL | - |
| DOUBLE | - |
| DOUBLE_PRECISION | - |
| FLOAT | - |
| INT | - |
| INTEGER | - |
| JSON | - |
| NCHAR | - |
| NUMERIC | - |
| NVARCHAR | - |
| REAL | - |
| SMALLINT | - |
| TEXT | - |
| TIME | - |
| TIMESTAMP | - |
| UUID | - |
| VBABINARY | - |
| VARCHAR | - |
UPPERCASE 最大的特点就是在 CREATE TABLE 不会转换这些类型,他们原封不动的将他们传递给后端。因此如果后端不支持会导致错误。
对于每一个支持的后端都可以从 sqlalchemy.dialects.[database] 中获取所有该数据库支持的 UPPERCASE 类型。
为特定后端使用 UPPERCASE 类型
如果想要编写移植更好的程序,通常的建议一定是使用 CamelCase 类型。不过 SQLAlchemy 提供了一个 TypeEngine.with_variant() 方法来让 CamelCase 和 UPPERCASE 共同起作用:
Python
from sqlalchemy import MetaData
from sqlalchemy import Table, Column, Integer, String
from sqlalchemy.dialects.mysql import VARCHAR
metadata_obj = MetaData()
user = Table(
"user",
metadata_obj,
Column("user_name", String(100), primary_key=True),
# 在所有后端使用 String
# 在 mysql 和 mariadb 上他使用字符集 utf8 的 VARCHAR(255)
# TypeEngine.with_variant(type:TypeEngine, *dialect_names)
# dialects 就是 url 前面的协议字符串
Column(
"bio",
String(255).with_variant(VARCHAR(255, charset="utf8"), "mysql", "mariadb"),
),
)