我正在查看 SQLModel 的文档。 python 库是由 FastAPI 的作者编写的,因此我渴望通过 SqlModel 利用无缝数据库集成。
在docs中,他通过图形化描述二分搜索来说明索引是什么以及它是如何工作的。所以我认为可以合理地得出 SQLModel 默认情况下可以通过 B-Tree 对给定变量进行索引的结论。
B 树(和二分搜索)对于基于范围和不等式的查询有意义。但是,通过基于哈希的索引可以大大加快相等或身份查询 (
name=='John'
) 的速度。但如果只能支持一种索引类型,B-Tree 显然比 hash 更有意义。
这是一个例子
from sqlmodel import Field, Session, SQLModel, create_engine, select
class Hero(SQLModel, table=True):
id: int | None = Field(default=None, primary_key=True)
name: str = Field(index=True)
secret_name: str
age: int | None = Field(default=None, index=True)
但是假设我想使用哈希索引,可以通过一些 SQLModel 配置来完成吗?
在底层,SQLModel 构建在 SQLAlchemy 之上。也许作为备份,我们应该降低一个级别并通过 SQLAlchemy 定义索引类型。理想情况下,可以避免构建数据库提供商特定的解决方案(例如:Postgres)。
SQLModel 允许我们在模型定义中使用 SQLAlchemy 的
__table_args__
属性。所以,为了
class Hero(SQLModel, table=True):
id: int | None = Field(default=None, primary_key=True)
name: str = Field()
secret_name: str
__table_args__ = (
Index("ix_hero_name", "name", postgresql_using="hash"),
)
与
connection_url = "postgresql://scott:[email protected]/mydb"
engine = create_engine(connection_url)
SQLModel.metadata.create_all(engine)
SQLAlchemy 生成
CREATE TABLE hero (
id SERIAL NOT NULL,
name VARCHAR NOT NULL,
secret_name VARCHAR NOT NULL,
PRIMARY KEY (id)
)
CREATE INDEX ix_hero_name ON hero USING hash (name)
其他方言会忽略
postgresql_using=
选项,所以
connection_url = "sqlite:///database.db"
engine = create_engine(connection_url)
SQLModel.metadata.create_all(engine)
产生
CREATE TABLE hero (
id INTEGER NOT NULL,
name VARCHAR NOT NULL,
secret_name VARCHAR NOT NULL,
PRIMARY KEY (id)
)
CREATE INDEX ix_hero_name ON hero (name)