我正在使用 FastAPI 和 pydantic 构建 API。
\n当我遵循 DDD / clean 架构(将模型的定义与持久层的定义分开)时,我在模型中使用标准 lib 数据类,然后使用命令式映射(即经典映射)将它们映射到 SQLAlchemy 表。
\n这很完美:
\n@dataclass\nclass User:\n name: str\n age: int\n\n@pydantic.dataclasses.dataclass\nclass PydanticUser(User):\n ...\nRun Code Online (Sandbox Code Playgroud)\n但是,我在定义具有自引用的类时遇到了问题。
\n从 pydantic\xe2\x80\x99s BaseModel 继承是可行的,但这与 SQLAlchemy 命令式映射不兼容,我想用它来坚持干净的架构/DDD 原则。
\nclass BaseModelPerson(BaseModel):\n name: str\n age: int\n parent_person: BaseModelPerson = None\n\nBaseModelPerson.update_forward_refs()\njohn = BaseModelPerson(name="John", age=49, parent_person=None)\ntim = BaseModelPerson(name="Tim", age=14, parent_person=john)\n\nprint(john)\n# BaseModelPerson(name=\'John\', age=49, parent_person=None)\nprint(tim)\n# BaseModelPerson(name=\'Tim\', age=14, parent_person=BaseModelPerson(name=\'John\', age=49, parent_person=None))\nRun Code Online (Sandbox Code Playgroud)\nfrom __future__ import annotations\nfrom …Run Code Online (Sandbox Code Playgroud) 我\xe2\x80\x99m 使用 Python 和干净的架构原则以及 TDD 构建一个应用程序。
\n某些单元测试需要对内存数据库执行一些原始 SQL 查询。
\n我正在尝试使用 pytest-postgres 从 sqlite 切换到 postgresql 内存数据。
\n s_tb_name = "tb_customer"\n ls_cols = ["first_name", "last_name", "email"]\n ls_vals = [\'("John", "Doe", "john.doe@mail.net")\',\n \'("Jane", "Doe", "jane.doe@mail.net")\',\n \'("Eric", "Dal", "eric.d@home.com")\']\n s_cols = \', \'.join(ls_cols)\n s_vals = \', \'.join(ls_vals)\n session.execute(f"INSERT INTO {s_tb_name} ({s_cols}) VALUES ({s_vals})")\nRun Code Online (Sandbox Code Playgroud)\nE sqlalchemy.exc.ProgrammingError: (psycopg2.errors.UndefinedColumn) column "John" does not exist\nE LINE 1: ..., email) …Run Code Online (Sandbox Code Playgroud) 我在 Python 项目中使用干净的架构和 TDD 开发方法。\n从 SQLAlchemy 1.3 更新到 SQLAlchemy 1.4 破坏了针对内存 Postgres DB 进行测试的能力,我无法\xe2\x80\x99找到如何修复问题。
\n遵循 DDD 原则,该项目使用新的命令式映射语法来取代传统的映射声明。
\n这是一个最小的(非)工作示例,改编自 SQLAlchemy 文档:\n https://docs.sqlalchemy.org/en/14/orm/mapping_styles.html#orm-imperative-mapping
\n它需要在本地安装并运行 PostgreSQL。
\nfrom sqlalchemy import MetaData, Table, Column, Integer, String\nfrom sqlalchemy.orm import registry\nfrom myapp import model\n\nmapper_registry = registry()\nmetadata = MetaData()\n\nuser_table = Table(\n \'tb_user\',\n mapper_registry.metadata,\n Column(\'id\', Integer, primary_key=True),\n Column(\'name\', String(50)),\n Column(\'fullname\', String(50)),\n Column(\'nickname\', String(12))\n)\n\nmapper_registry.map_imperatively(model.User, user_table)\nRun Code Online (Sandbox Code Playgroud)\nfrom dataclasses import dataclass\nfrom dataclasses import field\n\n@dataclass\nclass User:\n id: int = field(init=False)\n name: str = ""\n …Run Code Online (Sandbox Code Playgroud)