跳转到主要内容

一个用于从SQLAlchemy模型自动生成Strawberry GraphQL类型的库。

项目描述

strawberry-sqlalchemy-mapper

strawberry-sqlalchemy-mapper 是实现SQLAlchemy模型中的列和关系的自动生成的strawberry类型的最简单方式。

  • 无需手动列出 SQLAlchemy 模型中的每一列和关系,strawberry-sqlalchemy-mapper 允许您装饰一个类声明,它将自动为给定模型中所有列和关系(受以下限制)生成必要的 strawberry 字段。

  • 原生支持 SQLAlchemy 大多数常见类型。

  • 可扩展到任意的自定义 SQLAlchemy 类型。

  • 自动批量查询,避免在获取关系时出现 N+1 查询。

  • 支持 SQLAlchemy >=1.4.x

  • 轻量级且速度快。

入门指南

strawberry-sqlalchemy-mapper 可在 PyPi 上找到

pip install strawberry-sqlalchemy-mapper

首先,定义您的 sqlalchemy 模型

# models.py
from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()


class Employee(Base):
    __tablename__ = "employee"
    id = Column(UUID, primary_key=True)
    name = Column(String, nullable=False)
    password_hash = Column(String, nullable=False)
    department_id = Column(UUID, ForeignKey("department.id"))
    department = relationship("Department", back_populates="employees")


class Department(Base):
    __tablename__ = "department"
    id = Column(UUID, primary_key=True)
    name = Column(String, nullable=False)
    employees = relationship("Employee", back_populates="department")

接下来,使用 strawberry_sqlalchemy_mapper.type() 装饰类型,将其注册为给定 SQLAlchemy 模型的 strawberry 类型。这将自动为模型的列、关系、关联代理和混合属性添加字段。例如

# elsewhere
# ...
from strawberry_sqlalchemy_mapper import StrawberrySQLAlchemyMapper

strawberry_sqlalchemy_mapper = StrawberrySQLAlchemyMapper()


@strawberry_sqlalchemy_mapper.type(models.Employee)
class Employee:
    __exclude__ = ["password_hash"]


@strawberry_sqlalchemy_mapper.type(models.Department)
class Department:
    pass


@strawberry.type
class Query:
    @strawberry.field
    def departments(self):
        return db.session.scalars(select(models.Department)).all()


# context is expected to have an instance of StrawberrySQLAlchemyLoader
class CustomGraphQLView(GraphQLView):
    def get_context(self):
        return {
            "sqlalchemy_loader": StrawberrySQLAlchemyLoader(bind=YOUR_SESSION),
        }


# call finalize() before using the schema:
# (note that models that are related to models that are in the schema
# are automatically mapped at this stage -- e.g., Department is mapped
# because employee.department is a relationshp to Department)
strawberry_sqlalchemy_mapper.finalize()
# only needed if you have polymorphic types
additional_types = list(strawberry_sqlalchemy_mapper.mapped_types.values())
schema = strawberry.Schema(
    query=Query,
    mutation=Mutation,
    extensions=extensions,
    types=additional_types,
)

# You can now query, e.g.:
"""
query {
    departments {
        id
        name
        employees {
            edge {
                node {
                    id
                    name
                    department {
                        # Just an example of nested relationships
                        id
                        name
                    }
                }
            }
        }
    }
}
"""

限制

SQLAlchemy 模型 -> Strawberry 类型和接口应遵循一致的(可自定义)命名约定。这些可以通过在构建 mapper 时传递 model_to_type_namemodel_to_interface_name 来配置。

原生支持以下 SQLAlchemy 类型

Integer: int,
Float: float,
BigInteger: BigInt,
Numeric: Decimal,
DateTime: datetime,
Date: date,
Time: time,
String: str,
Text: str,
Boolean: bool,
Unicode: str,
UnicodeText: str,
SmallInteger: int,
SQLAlchemyUUID: uuid.UUID,
VARCHAR: str,
ARRAY[T]: List[T] # PostgreSQL array
JSON: JSON # SQLAlchemy JSON
Enum: (the Python enum it is mapped to, which should be @strawberry.enum-decorated)

可以通过传递 extra_sqlalchemy_type_to_strawberry_type_map 支持更多类型,尽管对 TypeDecorator 类型的支持未经验证。

关联代理应采用以下形式 association_proxy('relationship1', 'relationship2'),即,两个属性都应表示关系。

多态层次结构的根 受到支持,但也应通过 strawberry_sqlalchemy_mapper.interface() 注册,其具体类型及其子类应继承该接口

class Book(Model):
    id = Column(UUID, primary_key=True)


class Novel(Book):
    pass


class ShortStory(Book):
    pass


# in another file
strawberry_sqlalchemy_mapper = StrawberrySQLAlchemyMapper()


@strawberry_sqlalchemy_mapper.interface(models.Book)
class BookInterface:
    pass


@strawberry_sqlalchemy_mapper.type(models.Book)
class Book:
    pass


@strawberry_sqlalchemy_mapper.type(models.Novel)
class Novel:
    pass


@strawberry_sqlalchemy_mapper.type(models.ShortStory)
class ShortStory:
    pass

贡献

我们鼓励您为 strawberry-sqlalchemy-mapper 做出贡献!您做出的任何贡献都将受到高度重视。

如果您有改进此项目的建议,请 fork 仓库并创建一个 pull request。别忘了为该项目点个赞!再次感谢!

  1. Fork 项目
  2. 创建您的功能分支(git checkout -b feature)
  3. 提交您的更改(git commit -m '添加一些功能')
  4. 将更改推送到分支(git push origin feature)
  5. 打开 Pull Request

先决条件

本项目使用 pre-commit,请确保在做出任何更改之前安装它:

pip install pre-commit
cd strawberry-sqlalchemy-mapper
pre-commit install

最好更新挂钩到最新版本:

pre-commit autoupdate

别忘了告诉您的贡献者也安装并使用 pre-commit。

安装

pip install -r requirements.txt

安装 PostgreSQL 14+

测试

pytest

⚖️ 许可证

MIT © strawberry-sqlalchemy-mapper

项目详情


下载文件

下载您平台上的文件。如果您不确定选择哪个,请了解更多关于 安装软件包 的信息。

源分布

strawberry_sqlalchemy_mapper-0.4.4.tar.gz (24.5 kB 查看散列值)

上传时间

构建分布

strawberry_sqlalchemy_mapper-0.4.4-py3-none-any.whl (24.2 kB 查看散列值)

上传于 Python 3

由以下支持