具有数据类的SQLAlchemy默认不填充Postgres数据库

编程入门 行业动态 更新时间:2024-10-22 10:40:47
本文介绍了具有数据类的SQLAlchemy默认不填充Postgres数据库的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我正在使用 dataclasses 与SQLAlchemy经典映射范例相结合。当我定义 dataclass 并结合 int 和 str 字段SQLAlchemy不会填充 int 和 str s,但是会填充列出和日期时间字段。例如以下代码:

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) sessionmit()

这正确地填充了 person 对象在内存中,但是 commit 操作在postgres中生成以下数据( name 和 age 列为 null ):

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

如果我更改 Person 类,从 name 和 age 中删除​​默认值,然后将数据正确填充到postgres:

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)

请注意,我已验证在中创建 person 对象时在内存中正确填充 name 和 age 字段的类的版本。

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.

如何将SQLAlchemy经典映射与具有默认值的数据类一起使用?

How do I use SQLAlchemy classical mappings in conjunction with dataclasses with default values?

(Python 3.6,SQLAlchemy 1.2.16,PostgreSQL 11.2)

(Python 3.6, SQLAlchemy 1.2.16, PostgreSQL 11.2)

推荐答案

由于''和 0 分别是默认返回值 str()和 int()函数,可以使用以下代码插入这些默认值:

Since '' and 0 are respectively default returned values of str() and int() functions, you could use the following code to insert thoses defaults:

@dataclass class Person: id: int = None name: str = field(default_factory=str) age: int = field(default_factory=int) hobbies: List[str] = field(default_factory=list) birthday: datetime = field(default_factory=datetime)

不幸的是,由于某些原因,使用 default 参数函数中的 field()函数无法正常工作(可能是 dataclasses 向后移植的错误或误解...)。但是您仍然可以使用 default_factory 指定不同于''和 0 使用 lambda :

Unfortunately, for some reason, using default parameter of field() function does not work as we could expect (could be a bug of the dataclasses backport or a misunterstanding...). But you still can use the default_factory to specify values differents from '' and 0 using lambda:

@dataclass class Person: id: int = None name: str = field(default_factory=lambda: 'john doe') age: int = field(default_factory=lambda: 77) hobbies: List[str] = field(default_factory=list) birthday: datetime = field(default_factory=datetime)

更多推荐

具有数据类的SQLAlchemy默认不填充Postgres数据库

本文发布于:2023-08-05 21:29:15,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1308158.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:数据库   数据   SQLAlchemy   Postgres

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!