I'm developing a system using SQLALchemy to persist my data. I'd like to have objects of my default rows so I could use then when creating new instances.
This would be very good for me since some tables are supposed to have some default values. Imagine a simple relation between trow tables (order and order_status). When inserting values in order, it would be nice to have an easy way to use some of this default values already in order_status without having to query for them every time.
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()
For example, I'd like to create a new instance of Order using something like:
order = Order(value=10, order_status=OrderStatus.FINISHED)
Instead of:
finished_status = session.query(OrderStatus).filter_by(name='Finished').first()
order = Order(value=10, order_status=finished_status)
It does not need to be implemented exactly like my example, but I'd like something similar
You should take a look at the association_proxy
: https://docs.sqlalchemy.org/en/13/orm/extensions/associationproxy.html
The example pretty much fits your question. Your Order
could finally look somewhat like this (obviously not copy&paste'able):
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
In get_or_create_order_status
you probably have to go back to querying (at least initially to eg fill a cache).
If the OrderStatus
is actually as simple as in your question, maybe an enum
would do the trick as well. That would obviously be much easier to manage.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.