.. image:: https://github.com/agronholm/sqlacodegen/actions/workflows/test.yml/badge.svg :target: https://github.com/agronholm/sqlacodegen/actions/workflows/test.yml :alt: 构建状态 .. image:: https://coveralls.io/repos/github/agronholm/sqlacodegen/badge.svg?branch=master :target: https://coveralls.io/github/agronholm/sqlacodegen?branch=master :alt: 代码覆盖率
这是一个工具,可以读取现有数据库的结构并生成适当的SQLAlchemy模型代码,尽可能使用声明式风格。
这个工具是作为sqlautocode
_的替代品而编写的,sqlautocode存在多个问题(包括但不限于与Python 3和最新SQLAlchemy版本不兼容)。
.. _sqlautocode: http://code.google.com/p/sqlautocode/
特性
- 支持SQLAlchemy 2.x
- 生成的声明式代码几乎看起来像手写的
- 生成符合
PEP 8
_规范的代码 - 准确确定关系,包括多对多、一对一
- 自动检测连接表继承
- 出色的测试覆盖率
.. _PEP 8: http://www.python.org/dev/peps/pep-0008/
安装
安装方法:
pip install sqlacodegen
要包含对PostgreSQL CITEXT
扩展类型的支持(仅在少数环境下测试过),请指定 citext
额外选项:
pip install sqlacodegen[citext]
要包含对PostgreSQL GEOMETRY
、GEOGRAPHY
和 RASTER
类型的支持(仅在少数环境下测试过),请指定 geoalchemy2
额外选项:
要包含对PostgreSQL PGVECTOR
扩展类型的支持,请指定 pgvector
额外选项:
pip install sqlacodegen[pgvector]
.. code-block:: bash
pip install sqlacodegen[geoalchemy2]
快速入门
至少,你需要给sqlacodegen一个数据库URL。该URL直接传递给SQLAlchemy的 create_engine()
_ 方法,所以请参考 SQLAlchemy的文档
_ 了解如何构造正确的URL。
示例:
sqlacodegen postgresql:///some_local_db
sqlacodegen --generator tables mysql+pymysql://user:password@localhost/dbname
sqlacodegen --generator dataclasses sqlite:///database.db
查看通用选项列表:
sqlacodegen --help
.. _create_engine(): http://docs.sqlalchemy.org/en/latest/core/engines.html#sqlalchemy.create_engine .. _SQLAlchemy的文档: http://docs.sqlalchemy.org/en/latest/core/engines.html
可用生成器
选择生成器决定了
以下内置生成器可用:
tables
(仅生成Table
对象,适用于不想使用ORM的人)declarative
(默认选项;生成继承自declarative_base()
的类)dataclasses
(生成基于dataclass的模型;仅适用于v1.4+)sqlmodels
(为SQLModel_生成模型类)
.. _SQLModel: https://sqlmodel.tiangolo.com/
生成器特定选项
以下选项可以通过 --options
传递开启(多个值必须用逗号分隔,例如 --options noconstraints,nobidi
):
-
tables
noconstraints
:忽略约束(外键、唯一键等)nocomments
:忽略表/列注释noindexes
:忽略索引
-
declarative
tables
的所有选项use_inflect
:使用inflect
库命名类和关系(将复数名称转为单数;详见下文)nojoined
:不尝试检测连接类继承(详见下文)nobidi
:以单向方式生成关系,因此只有多对一或多对多关系的第一侧获得关系属性,如v2.X中所示
-
dataclasses
declarative
的所有选项
-
sqlmodel
declarative
的所有选项
模型类生成器
生成类的代码生成器尽可能生成模型类。在以下两种情况下会生成 Table
而不是模型类:
- 表没有主键约束(SQLAlchemy要求每个模型类都有主键)
- 表是两个其他表之间的关联表(具体见下文)
模型类命名逻辑 ++++++++++++++
默认情况下,表名转换为符合PEP 8规范的有效类名,方法是将所有不适合Python标识符的字符替换为 _
。然后,每个有效部分(由下划线分隔)首字母大写并连接在一起,消除下划线。例如,example_name
变成 ExampleName
。
如果使用 use_inflect
选项,表名(假定为英语)会使用"inflect"库转换为单数形式。例如,sales_invoices
变成 SalesInvoice
。由于表名并不总是英语,且变形过程远非完美,默认情况下禁用变形。
关系检测逻辑 ++++++++++++
根据现有外键约束检测关系,如下:
- 多对一:表上存在外键约束
- 一对一:与多对一相同,但涉及的列上存在唯一约束
- 多对多:(在
sqlmodel
生成器中未实现)在两个表之间发现存在关联表
如果一个表满足以下所有条件,则被视为关联表:
#. 恰好有两个外键约束 #. 所有列都涉及上述约束
关系命名逻辑 ++++++++++++
关系通常根据对方类的表名命名。例如,如果一个类与另一个表名为 companies
的类有关系,该关系将被命名为 companies
(除非启用了 use_inflect
选项,在这种情况下,对于多对一或一对一关系,它将被命名为 company
)。
然而,对于单列多对一和一对一关系,有一种特殊情况,即如果列名类似 employer_id
。这时,由于 _id
后缀,关系将被命名为 employer
。
对于自引用关系,关系的反向侧将以 _reverse
后缀命名。
自定义代码生成逻辑
如果内置生成器及其所有选项不能完全满足你的需求,你可以通过继承现有代码生成器类来自定义逻辑。重写你需要的方法,然后在 sqlacodegen.generators
命名空间中添加一个入口点
_,指向你的新类。一旦入口点就位(通常需要用 pip install
安装项目),你就可以使用 --generator <你的入口点>
来调用你的自定义代码生成器。
有关示例,你可以查看sqlacodegen自己在 pyproject.toml
_ 中的入口点。
.. _入口点: https://setuptools.readthedocs.io/en/latest/userguide/entry_point.html .. _pyproject.toml: https://github.com/agronholm/sqlacodegen/blob/master/pyproject.toml
获取帮助
如果你遇到问题或有其他问题,可以在 sqlacodegen讨论论坛
_ 上开始讨论。或者,你也可以在Gitter上的sqlalchemy_房间碰碰运气。
.. _sqlacodegen讨论论坛: https://github.com/agronholm/sqlacodegen/discussions/categories/q-a .. _sqlalchemy: https://app.gitter.im/#/room/#sqlalchemy_community:gitter.im