gpt4 book ai didi

python - SQLAlchemy 嵌套模型创建单行

转载 作者:行者123 更新时间:2023-12-05 02:18:16 24 4
gpt4 key购买 nike

我想从 q2 创建一个新对象,但它失败了,因为 Question 类期望选项是选项的字典,而它接收的是字典的字典。

因此,对于嵌套模型,解包显然会失败。

处理此问题的最佳方法是什么?对于嵌套模型,是否存在与 **dict 的优雅等同的东西?

主.py

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

import models.base

from models.question import Question
from models.option import Option


engine = create_engine('sqlite:///:memory:')

models.base.Base.metadata.create_all(engine, checkfirst=True)
Session = sessionmaker(bind=engine)
session = Session()


def create_question(q):

# The following hard coding works:
# q = Question(text='test text',
# frequency='test frequency',
# options=[Option(text='test option')]
# )

question = Question(**q)
session.add(question)
session.commit()

q1 = {
'text': 'test text',
'frequency': 'test frequency'
}

q2 = {
'text': 'test text',
'frequency': 'test frequency',
'options': [
{'text': 'test option 123'},
]
}

create_question(q1)
# create_question(q2) FAILS

base.py

from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()

from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()

问题.py

from sqlalchemy import *
from sqlalchemy.orm import relationship
from .base import Base


class Question(Base):

__tablename__ = 'questions'

id = Column(Integer, primary_key=True)

text = Column(String(120), nullable=False)
frequency = Column(String(20), nullable=False)
active = Column(Boolean(), default=True, nullable=False)

options = relationship('Option', back_populates='question')

def __repr__(self):
return "<Question(id={0}, text={1}, frequency={2}, active={3})>".format(self.id, self.text, self.frequency, self.active)

option.py

from sqlalchemy import *
from sqlalchemy.orm import relationship
from .base import Base


class Option(Base):

__tablename__ = 'options'

id = Column(Integer, primary_key=True)

question_id = Column(Integer, ForeignKey('questions.id'))
text = Column(String(20), nullable=False)

question = relationship('Question', back_populates='options')

def __repr__(self):
return "<Option(id={0}, question_id={1}, text={2})>".format(self.id, self.question_id, self.text)

最佳答案

我喜欢@Abdou 提供的答案,但想看看我能不能让它更通用一点。

我最终得出以下结论,它应该可以处理任何嵌套模型。

from sqlalchemy import event, inspect


@event.listens_for(Question, 'init')
@event.listens_for(Option, 'init')
def received_init(target, args, kwargs):

for rel in inspect(target.__class__).relationships:

rel_cls = rel.mapper.class_

if rel.key in kwargs:
kwargs[rel.key] = [rel_cls(**c) for c in kwargs[rel.key]]

监听任何指定模型的 init 事件,检查与传入的 kwargs 匹配的关系,然后将它们转换为关系的匹配类。

如果有人知道如何设置它以便它可以在所有模型上工作而不是指定它们,我将不胜感激。

关于python - SQLAlchemy 嵌套模型创建单行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45909405/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com