我在用dataclasses
与 SQLAlchemy 经典映射范例相结合。当我定义一个dataclass
与默认值相结合int
and str
SQLAlchemy 不会填充字段int
and str
s,但它确实填充了List
and datetime
字段。例如下面的代码:
from dataclasses import dataclass, field
from typing import List
from datetime import datetime
from sqlalchemy import create_engine, MetaData, Table, Column, Integer, String, ARRAY, TIMESTAMP
from sqlalchemy.orm import sessionmaker, mapper
metadata = MetaData()
person_table = \
Table('people', metadata,
Column('id', Integer, primary_key=True, autoincrement=True),
Column('name', String(255)),
Column('age', Integer),
Column('hobbies', ARRAY(String)),
Column('birthday', TIMESTAMP)
)
@dataclass
class Person:
id: int = None
name: str = ''
age: int = 0
hobbies: List[str] = field(default_factory=list)
birthday: datetime = field(default_factory=datetime)
mapper(Person, person_table)
engine = create_engine('postgresql://postgres@localhost:32771/test', echo=True)
metadata.create_all(engine)
session = sessionmaker(bind=engine)()
person = Person(id=None, name='Robby', age=33, hobbies=['golf', 'hiking'], birthday=datetime(1985, 7, 25))
session.add(person)
session.commit()
这正确地填充了person
内存中的对象,但是commit
操作在 postgres 中产生以下数据(name
and age
列是null
):
id | name | age | hobbies | birthday
----+------+-----+---------------+---------------------
1 | | | {golf,hiking} | 1985-07-25 00:00:00
如果我改变Person
从中删除默认值的类name
and age
然后数据在 postgres 中正确填充:
@dataclass
class Person:
id: int = None
name: str
age: int
hobbies: List[str] = field(default_factory=list)
birthday: datetime = field(default_factory=datetime)
请注意,我已经验证过,当person
对象是在该类的“无默认”版本中创建的name
and age
字段已正确填充在内存中。
如何将 SQLAlchemy 经典映射与具有默认值的数据类结合使用?
(Python 3.6、SQLAlchemy 1.2.16、PostgreSQL 11.2)