SQLAlchemy 声明性数据类映射:如何创建非必需列?

问题描述 投票:0回答:1

我正在尝试弄清楚如何在 SQLAlchemy 中对数据类使用声明性映射。

设置:


from dotenv import load_dotenv
import os
from sqlalchemy.engine import URL

#test abc

load_dotenv()

url_object = URL.create(
    "postgresql+psycopg2",
    username=os.environ.get('DBUSER'),
    password=os.environ.get('DBPASS'),  # plain (unescaped) text
    host=os.environ.get('DBIP'),
    database=os.environ.get('DBNAME'),
    port=os.environ.get('DBPORT')
)

from sqlalchemy import create_engine, Table, Column, ForeignKey, Integer, String, Boolean


engine = create_engine(url_object,
                       echo=True)




from typing_extensions import Annotated
from typing import List
from typing import Optional
from sqlalchemy import ForeignKey
from sqlalchemy import String
from sqlalchemy.orm import DeclarativeBase
from sqlalchemy.orm import Mapped
from sqlalchemy.orm import MappedAsDataclass
from sqlalchemy.orm import mapped_column
from sqlalchemy.orm import relationship

from sqlalchemy.orm import registry
reg = registry()


class Base(MappedAsDataclass, DeclarativeBase):
    """subclasses will be converted to dataclasses"""

我可以像这样创建一个简单的映射类和关联表:

class Test(Base):
    __tablename__ = 'test'
    id: Mapped[int] = mapped_column(init=False, primary_key=True)
    intVar: Mapped[int]
    strVar: Mapped[str]

Test.__table__

Base.metadata.create_all(engine)

表按预期创建,包含“id”、“intVar”和“strVar”列

但是,当我尝试使用默认值创建变量时,不会创建这些列,我的表只有前四个。当我查看表 test2 时,我只看到前四列,没有看到最后三列。所有未创建列的变量都有默认值:

import datetime

class Test2(Base):
    __tablename__ = 'test2'
    id: Mapped[int] = mapped_column(init=False, primary_key=True)
    intVar: Mapped[int]
    strVar: Mapped[str]
    anotherVar: Mapped[str]
    optVar: Mapped[Optional[str]] = ''
    yaVAR: Mapped[str] = ''
    date: Mapped[datetime.datetime] = datetime.datetime.now()

Test2.__table__

Base.metadata.create_all(engine)

但是,据我所知,我需要可选变量的默认值,否则如果我尝试创建一个没有“可选”变量的类实例,它会抱怨缺少位置参数:

import datetime

class Test3(Base):
    __tablename__ = 'test3'
    id: Mapped[int] = mapped_column(init=False, primary_key=True)
    intVar: Mapped[int]
    strVar: Mapped[str]
    anotherVar: Mapped[str]
    optVar: Mapped[Optional[str]]
    yaVAR: Mapped[str]
    date: Mapped[datetime.datetime] = datetime.datetime.now()

Test3.__table__

Base.metadata.create_all(engine)


t3 = Test3(intVar = 0, strVar = 'abc', anotherVar = 'xyz', optVar = "bs", yaVAR='morebs', date = datetime.datetime.now())

t4 = Test3(intVar = 0, strVar = 'abc', anotherVar = 'xyz', yaVAR='morebs', date = datetime.datetime.now())


t4 = Test3(intVar = 0, strVar = 'abc', anotherVar = 'xyz', yaVAR='morebs', date = datetime.datetime.now())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __init__() missing 1 required positional argument: 'optVar'

那么我如何制作一个带有可选变量的数据类,并在创建表时创建列?

python sqlalchemy orm default-value python-dataclasses
1个回答
0
投票

好的,所以我误解了如何创建可选变量。当我使用

mapped_column(default=None)
而不是
Mapped[Optional[]]
时,一切都按预期工作。

class Error(Base):
    __tablename__ = 'errors'
    id: Mapped[int] = mapped_column(init=False, primary_key=True)
    feed_id: Mapped[int]
    url: Mapped[str]
    error: Mapped[str]
    step: Mapped[str]
    host: Mapped[str]
    parameters: Mapped[Optional[str]] = mapped_column(default=None)
    uagent: Mapped[Optional[str]] = mapped_column(default=None)
    proxy: Mapped[Optional[str]] = mapped_column(default=None)
    status_code: Mapped[Optional[int]] = mapped_column(default=None)
    date: Mapped[datetime.datetime] = mapped_column(default=None)
© www.soinside.com 2019 - 2024. All rights reserved.