sqlalchemy:与多个表的非平凡的一对一关系

问题描述 投票:0回答:1

我正在努力为我的Flask应用程序创建数据库模型。

让我们考虑一下我的产品类型很少,并且由于我的应用程序的性质,我希望每个产品都有单独的表,同时将通用属性保存在公共表中:

例:

  • 产品表 id type name price 1 'motorcycle' 'Harley' 10000.00 2 'book' 'Bible' 9.99
  • 摩托车桌 id manufacturer model max_speed 1 'Harley-Davidson' 'Night Rod Special' 150
  • 书桌 id author pages 2 'Some random dude' 666

需要考虑的事项:

  • 所有表都有一对一的关系
  • 在产品表中使用motorcycle_id,book_id,etc_id不是一种选择
  • 在产品表中使用product_id是可以接受的
  • 双向关系

我该如何宣布这种关系?

python sqlalchemy flask-sqlalchemy
1个回答
3
投票

您正在寻找joined table inheritance。基类和每个子类各自创建自己的表,每个子类都有一个指向基表的外键主键。无论您是查询基类还是子类,SQLAlchemy都会自动处理连接。

以下是一些产品的工作示例:

from decimal import Decimal
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey, Numeric
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

engine = create_engine('sqlite:///:memory:', echo=True)
session = sessionmaker(bind=engine)()
Base = declarative_base(bind=engine)


class Product(Base):
    __tablename__ = 'product'

    id = Column(Integer, primary_key=True)
    type = Column(String, nullable=False)
    name = Column(String, nullable=False, default='')
    price = Column(Numeric(7, 2), nullable=False, default=Decimal(0.0))

    __mapper_args__ = {
        'polymorphic_on': type,  # subclasses will each have a unique type
    }


class Motorcycle(Product):
    __tablename__ = 'motorcycle'

    # id is still primary key, but also foreign key to base class
    id = Column(Integer, ForeignKey(Product.id), primary_key=True)
    manufacturer = Column(String, nullable=False, default='')
    model = Column(String, nullable=False, default='')
    max_speed = Column(Integer, nullable=False, default=0)

    __mapper_args__ = {
        'polymorphic_identity': 'motorcycle',  # unique type for subclass
    }


class Book(Product):
    __tablename__ = 'book'

    id = Column(Integer, ForeignKey(Product.id), primary_key=True)
    author = Column(String, nullable=False, default='')
    pages = Column(Integer, nullable=False, default=0)

    __mapper_args__ = {
        'polymorphic_identity': 'book',
    }


Base.metadata.create_all()

# insert some products
session.add(Book())
session.add(Motorcycle())
session.commit()

print(session.query(Product).count())  # 2 products
print(session.query(Book).count())  # 1 book
最新问题
© www.soinside.com 2019 - 2024. All rights reserved.