Leo*_*hen 6 python sqlalchemy mypy
Mypy 将 ORM 不可为 null 的实例属性推断为可选。
文件名:test.py
from sqlalchemy.orm import decl_api, registry
from sqlalchemy import BigInteger, Column, String
mapper_registry = registry()
class Base(metaclass=decl_api.DeclarativeMeta):
__abstract__ = True
registry = mapper_registry
metadata = mapper_registry.metadata
__init__ = mapper_registry.constructor
class Person(Base):
__tablename__ = "persons"
id = Column(BigInteger, primary_key=True, autoincrement=True)
name = Column(String(40), nullable=False)
def main(person: Person):
person_id = person.id
person_name = person.name
reveal_locals()
Run Code Online (Sandbox Code Playgroud)
运行mypy test.py产量:
test.py:27: note: Revealed local types are:
test.py:27: note: person: test.Person
test.py:27: note: person_id: Union[builtins.int, None]
test.py:27: note: person_name: Union[builtins.str, None]
Run Code Online (Sandbox Code Playgroud)
据我的理解,person_id和person_name应该分别是int和 ,str因为它们被设置为不可空。
我在这里缺少什么?
相关库:
SQLAlchemy 1.4.25
sqlalchemy2-stubs 0.0.2a15
mypy 0.910
mypy-extensions 0.4.3
Run Code Online (Sandbox Code Playgroud)
小智 1
nullable=False我在使用 mypy评估列时遇到了同样的问题。我的一位队友在 SqlAlchemy 文档中找到了答案:
\n\n默认情况下,这些类型始终被视为可选,即使对于主键和不可为 null 的列也是如此。原因是因为虽然数据库列 \xe2\x80\x9cid\xe2\x80\x9d 和 \xe2\x80\x9cname\xe2\x80\x9d 可以\xe2\x80\x99t 为 NULL,但 Python\nattributes id 和如果没有显式的\n构造函数,名称肯定可以是 None:
\n
他们在那篇文章中还列出了一些缓解措施,其中明确声明要映射的列类型。
\n