Как сделать строки по умолчанию / уже существующие как готовые к использованию объекты с помощью SQLAlchemy? - PullRequest
0 голосов
/ 10 марта 2020

Я разрабатываю систему с использованием SQLALchemy для сохранения моих данных. Я хотел бы иметь объекты из моих строк по умолчанию, чтобы потом использовать их при создании новых экземпляров.

Это было бы очень хорошо для меня, так как некоторые таблицы должны иметь некоторые значения по умолчанию. Представьте себе простую связь между таблицами trow (order и order_status). При вставке значений по порядку было бы неплохо иметь простой способ использовать некоторые из этих значений по умолчанию уже в order_status без необходимости каждый раз запрашивать их.

from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, sessionmaker


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

Base = declarative_base()

class Order(Base):
    __tablename__ = 'order'

    id = Column(Integer, primary_key=True)
    order_status_id = Column(Integer, ForeignKey('order_status.id'))
    value = Column(Integer)

    order_status = relationship('OrderStatus', lazy=True, uselist=False)

class OrderStatus(Base):
    __tablename__ = 'order_status'

    id = Column(Integer, primary_key=True)
    name = Column(String(32))

Base.metadata.create_all(engine)

Session = sessionmaker(bind=engine)
session = Session()

finished = OrderStatus(name='Finished')
session.add(finished)
session.commit()

Например, я бы хотел создать новый экземпляр Order, используя что-то вроде:

order = Order(value=10, order_status=OrderStatus.FINISHED)

Вместо:

finished_status = session.query(OrderStatus).filter_by(name='Finished').first()
order = Order(value=10, order_status=finished_status)

Его не нужно реализовывать точно так же, как в моем примере, но я бы хотел что-то аналогичный

1 Ответ

0 голосов
/ 10 марта 2020

Вы должны взглянуть на association_proxy: https://docs.sqlalchemy.org/en/13/orm/extensions/associationproxy.html

Пример в значительной степени соответствует вашему вопросу. Ваш Order может наконец-то выглядеть примерно так (очевидно, не для копирования и вставки):

class OrderStatus(Base):
    ...

class Order(Base):
    __tablename__ = 'order'

    id = Column(Integer, primary_key=True)
    order_status_id = Column(Integer, ForeignKey('order_status.id'))
    value = Column(Integer)

    _order_status = relationship('OrderStatus', lazy=True, uselist=False)
    order_status = association_proxy('_order_status', 'name', creator=get_or_create_order_status)

def get_or_create_order_status(name):
    # get or create a order status by name

В get_or_create_order_status вам, вероятно, придется go вернуться к запросам (по крайней мере на начальном этапе, например, для заполнения кеша). ).

Если OrderStatus на самом деле так же просто, как и в вашем вопросе, возможно, enum также поможет. Это, очевидно, было бы гораздо проще.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...