Mat*_*ger 5 python sqlalchemy alembic sqlmodel
我正在尝试在 SQLModel 中创建一个基类,如下所示:
class BaseModel(SQLModel):
@declared_attr
def __tablename__(cls) -> str:
return cls.__name__
guid: Optional[UUID] = Field(default=None, primary_key=True)
class SequencedBaseModel(BaseModel):
sequence_id: str = Field(sa_column=Column(VARCHAR(50), server_default=text(f"SELECT '{TABLENAME}_' + convert(varchar(10), NEXT VALUE FOR dbo.sequence)")))
Run Code Online (Sandbox Code Playgroud)
所以我得到了一个这样的表:
class Project(SequencedBaseModel):
...
Run Code Online (Sandbox Code Playgroud)
Project其中 alembic 将为包含列guid和的表生成迁移sequence_id。序列 ID 的默认值是使用以下命令生成的序列
SELECT '{TABLENAME}_' + convert(varchar(10), NEXT VALUE FOR dbo.sequence)
Run Code Online (Sandbox Code Playgroud)
并且应该将值Project_1, ,Project_2插入到项目表中...
关于如何动态设置表名有什么想法吗?我无法使用构造函数来设置列,因为 alembic 忽略它们,我无法访问该__tablename__()函数,或者cls,因为列是静态的...
不幸的是,如果您有一个依赖于 a 的属性@declared_attr,它也必须是 a @declared_attr,因为 SqlAlchemy 将等到整个映射完成并且类获得要解析的实际表(至少,这是我的理解)。现在:declared_attr(s) 是一个 SqlAlchemy 概念,而 的想法Field是一个 SQLModel 概念,并且它们似乎不会就这种“”“deferred””属性事物相互交谈(“”“deferred”” “从某种意义上说,在映射完成并且表已知之前不会对其进行评估,而不是像等待访问一样推迟)......至少,据我所知。
您可以(也许?希望如此?)执行类似于此 SQLModel GitHub 问题中建议的操作:“推迟” SqlAlchemy 列并为 SQLModel 字段指定别名:
\nclass SequencedBaseModel(BaseModel):\n sequence_id: str = Field(alias="sequence_id")\n\n @declared_attr\n def sequence_id(cls):\n return Column(\n \'sequence_id\',\n VARCHAR(50),\n server_default=text(f"SELECT \'{cls.__tablename__}_\'"\n f" + convert(varchar(10), NEXT VALUE FOR dbo.sequence)"))\n\n\nclass Project(SequencedBaseModel, table=True):\n pass\nRun Code Online (Sandbox Code Playgroud)\n运行将生成一个迁移文件,并在\'s中扩展了alembic revision --autogenerate -m "init"正确的__tablename__ + \'_\'(意思是:) :Product_server_defaultSELECT...
def upgrade() -> None:\n op.create_table(\'Project\',\n sa.Column(\'guid\', sqlmodel.sql.sqltypes.GUID(), nullable=False),\n sa.Column(\'sequence_id\', sa.VARCHAR(length=50), server_default=sa.text("SELECT \'Project_\' + convert(varchar(10), NEXT VALUE FOR dbo.sequence)"), nullable=True),\n sa.PrimaryKeyConstraint(\'guid\'),\n # ... \n # ... \nRun Code Online (Sandbox Code Playgroud)\n这假设您的 alembic 环境已正确配置。我忍不住指出 alembic 将使用属性sqlmodel.sql.sqltypes.GUID()的列类型生成迁移guid,因此您需要确保sqlmodel在每个迁移文件上导入该包。可能通过按照此链接中script.py.mako所述编辑模板,其中显示您必须添加.import sqlmodel # NEW
\xe2\x9a\xa0\xef\xb8\x8f 我试图测试这个,但我不完全知道来自哪里dbo.sequence(也许是 SQL 服务器?)。我使用PostgreSQL 序列(我将其命名为so75719072)来模拟它。这意味着我无法确认 的语法DEFAULT SELECT...在您的情况下是否有效。我非常怀疑您是否能够使用 a 的结果SELECT作为列的默认值,但希望我错了。
import uuid\nfrom typing import Optional\nfrom uuid import UUID\n\nfrom sqlalchemy import Column, VARCHAR, text\nfrom sqlalchemy.orm import declared_attr\nfrom sqlmodel import SQLModel, Field, create_engine, Session, select\n\n\nclass BaseModel(SQLModel):\n __table_args__ = {\'schema\': \'SO-75719072\'}\n\n @declared_attr\n def __tablename__(cls) -> str:\n return cls.__name__\n\n guid: Optional[UUID] = Field(default=None, primary_key=True)\n\n\nclass SequencedBaseModel(BaseModel):\n sequence_id: str = Field(alias="sequence_id")\n\n @declared_attr\n def sequence_id(cls):\n return Column(\n \'sequence_id\',\n VARCHAR(50),\n server_default=text(f"nextval(\'so75719072\')"))\n\n\nclass Project(SequencedBaseModel, table=True):\n pass\n\n\nif __name__ == "__main__":\n engine = create_engine(\n "postgresql+psycopg2://postgres:postgrespw@localhost:32768/stackoverflow")\n\n with Session(engine) as session:\n for i in range(3):\n proj1 = Project(guid=uuid.uuid4())\n session.add(proj1)\n session.commit()\n\n with Session(engine) as session:\n statement = select(Project).where(Project.sequence_id.in_(["1", "2", "3"]))\n for project in session.exec(statement):\n print(f"guid: {project.guid}")\nRun Code Online (Sandbox Code Playgroud)\n产生以下输出:
\nguid: c5e5902d-e224-48f1-95f5-fa47a73f7b05\nguid: 1c25550b-258c-49c5-9acc-90ae7ad8460c\nguid: eb84e90c-9449-4974-8eb4-bad98728b0f9\nRun Code Online (Sandbox Code Playgroud)\n它来自 Postgres 中的下表:
\n# select * from "SO-75719072"."Project";\n guid | sequence_id\n--------------------------------------+-------------\n c5e5902d-e224-48f1-95f5-fa47a73f7b05 | 1\n 1c25550b-258c-49c5-9acc-90ae7ad8460c | 2\n eb84e90c-9449-4974-8eb4-bad98728b0f9 | 3\n(3 rows)\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
1245 次 |
| 最近记录: |