I am using dataclasses combined with the SQLAlchemy classical mapping paradigm. When I define a dataclass combined with default values for the int and str fields SQLAlchemy does not populate the int and strs, but it does populate the List and datetime fields. For example the following code:
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()
This correctly populates the person object in memory, but the commit operation produces the following data in postgres (the name and age columns are null):
id | name | age | hobbies | birthday
----+------+-----+---------------+---------------------
1 | | | {golf,hiking} | 1985-07-25 00:00:00
If I change the Person class to remove the default values from name and age then the data is populated correctly in postgres:
@dataclass
class Person:
id: int = None
name: str
age: int
hobbies: List[str] = field(default_factory=list)
birthday: datetime = field(default_factory=datetime)
Note, I have verified that when the person object is created in the "no-default" version of the class that the name and age fields are populated correctly in memory.
How do I use SQLAlchemy classical mappings in conjunction with dataclasses with default values?
(Python 3.6, SQLAlchemy 1.2.16, PostgreSQL 11.2)
defaultandserver_default?