zoukankan      html  css  js  c++  java
  • 理解SQLAlchemy的表继承关系(4)--高级应用

    class Entry(AbstractConcreteBase, db.Model):
        """Base Class of Entry."""
     
        id = db.Column(db.Integer, primary_key=True, nullable=False)
        created = db.Column(db.DateTime, nullable=False)
        post_id = declared_attr(lambda c: db.Column(db.ForeignKey("post.id")))
        post = declared_attr(lambda c: db.relationship("Post", lazy="joined"))
     
        @declared_attr
        def __tablename__(cls):
            return cls.__name__.lower()
     
        @declared_attr
        def __mapper_args__(cls):
            # configurate subclasses about concrete table inheritance
            return {'polymorphic_identity': cls.__name__,
                    'concrete': True} if cls.__name__ != "Entry" else {}
     
    class TextEntry(Entry):
        """Text and Article Entry."""
     
        text = db.deferred(db.Column(db.Text, nullable=False))
     
    class PhotoEntry(Entry):
        """Photo Entry."""
     
        path = db.deferred(db.Column(db.String(256), nullable=False))

    以上Entry是一个基类,没有对应的数据库表,TextEntry和PhotoEntry均继承自Entry。

    class Post(db.Model):
        """An Post."""
     
        id = db.Column(db.Integer, primary_key=True, nullable=False)
        description = db.Column(db.Unicode(140), nullable=False)
        entries = db.relationship(Entry, lazy="dynamic")

    以上是我们一个应用示例,Post有一个entries皇粮指向不同的entry,在上述代码中我们直接使用relationship来跟Entry创建一个一对多的关系,

    理想情况应该是post的entries可以包含不同的Entry,如

    >>Post.entries.query.all()
    [<PhotoEntry 'Title' created by tonyseek>,
     <PhotoEntry 'TITLE 2' created by tonyseek>,
     <PhotoEntry 'Title 3' created by tonyseek>,
     <PhotoEntry 'Title 4' created by tonyseek>,
     <TextEntry 'Title' created by tonyseek>]

    但上述代码会出错,出错的原因是因为Entry是一个抽象基类,在数据库中并没有创建对应的数据库表,所以不能创建一对多关系。

    幸运的是AbstractConcreteBase提供了__delcare_last__

    可以用来解决这些问题,代码如下:

    class Post(db.Model):
        id = db.Column(db.Integer, primary_key=True, nullable=False)
        description = db.Column(db.Unicode(140), nullable=False)
     
        @classmethod
        def __declare_last__(cls):
            cls.entries = db.relationship(Entry, viewonly=True)
     
        def attach_entries(self, entries):
            """Attach Entries To This Post.
            Example:
                >>> post = Post("An Interesting News", "Wow !!!")
                >>> text_entry = TextEntry(*t_args)
                >>> photo_entry = PhotoEntry(*p_args)
                >>> post.attach_entries([text_entry, photo_entry])
                >>> len(post.entries)
                2
                >>> db.session.commit()
                >>>
            """
            for entry in entries:
                self.entries.append(entry)
                entry.post = self
                db.session.add(entry)
  • 相关阅读:
    CMD 常用命令
    CMD 删除脚本
    HAproxy 介绍
    HAproxy 配置参数详解
    HAproxy 源码包安装
    lvs keepalived 安装配置详解【转】
    linux下负载均衡(LVS安装与配置)【转】
    CentOS 6.3下部署LVS(NAT)+keepalived实现高性能高可用负载均衡【转】
    Linux负载均衡软件LVS之二(安装篇)[转]
    Mysql + keepalived 实现双主热备读写分离【转】
  • 原文地址:https://www.cnblogs.com/miaoweiye/p/12659536.html
Copyright © 2011-2022 走看看