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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了sqlalchemy:与多个表的非平凡的一对一关系相关的知识,希望对你有一定的参考价值。

我正在努力为我的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是可以接受的
  • 双向关系

我该如何宣布这种关系?

答案

您正在寻找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

以上是关于sqlalchemy:与多个表的非平凡的一对一关系的主要内容,如果未能解决你的问题,请参考以下文章

ORM SQLAlchemy 表于表的关系

SQLAlchemy(三):外键连表关系

SQLAlchemy学习-4.一对一关系

SQLAlchemy学习-4.一对一关系

深入浅出Flask(49):flask_sqlalchemy的创建一对多的关系表

雄辩的,每个表的多个关系