Python 多态属于炼金术中的关系?

Python 多态属于炼金术中的关系?,python,sqlalchemy,flask-sqlalchemy,Python,Sqlalchemy,Flask Sqlalchemy,我正在使用Rails项目中的一个数据库,并试图在其上构建一个Flask应用程序 这里有一些多态关联,我不知道如何使用炼金术进行复制 例如,有一个属性为id,url,photoable\u id,photoable\u type的“Photo”模型,它可能属于艺术家,组织,或事件。在我拥有的数据库中,Artist、Organization和Event表没有对照片的引用 我在SQLAlchemy中找到了多态关联,但它需要创建一个关联表——有没有办法按原样使用模式呢?我要找的是 以下是一对多关系的示例

我正在使用Rails项目中的一个数据库,并试图在其上构建一个Flask应用程序

这里有一些多态关联,我不知道如何使用炼金术进行复制

例如,有一个属性为
id
url
photoable\u id
photoable\u type
的“Photo”模型,它可能属于
艺术家
组织
,或
事件
。在我拥有的数据库中,
Artist
Organization
Event
表没有对照片的引用

我在SQLAlchemy中找到了多态关联,但它需要创建一个关联表——有没有办法按原样使用模式呢?

我要找的是

以下是一对多关系的示例:

from app import db
from datetime import datetime
from sqlalchemy import event, and_
from sqlalchemy.orm import relationship, foreign, remote, backref


class HasPhotos():
    pass

class Photo(db.Model):
    __tablename__   = 'photos'
    id              = db.Column(db.Integer(), primary_key=True)
    image           = db.Column(db.String())
    photoable_id    = db.Column(db.Integer())
    photoable_type  = db.Column(db.String(50))
    created_at      = db.Column(db.DateTime(), default=datetime.utcnow)
    updated_at      = db.Column(db.DateTime(), default=datetime.utcnow)

    @property
    def parent(self):
        return getattr(self, 'parent_{}'.format(self.photoable_type))



@event.listens_for(HasPhotos, 'mapper_configured', propagate=True)
def setup_listener(mapper, class_):
    name = class_.__name__
    type = name.lower()
    class_.photos = relationship(Photo,
                        primaryjoin=and_(
                                        class_.id == foreign(remote(Photo.photoable_id)),
                                        Photo.photoable_type == type
                                    ),
                        backref=backref(
                                'parent_{}'.format(type),
                                primaryjoin=remote(class_.id) == foreign(Photo.photoable_id)
                                )
                        )
    @event.listens_for(class_.photos, 'append')
    def append_photo(target, value, initiator):
        value.photoable_type = type
然后,当定义一个类来建立这种关系时,只需继承自
hasphots
,例如

class Artist(HasPhotos, db.Model):
    pass
要建立一对一的关系,只需将关键字参数
uselist=False
添加到
relationship()
调用中,而不是侦听
append
事件,而是侦听
set
事件,例如:

@event.listens_for(class_.photo, 'set')
def set_photo(target, value, old_value, initiator):
    value.photoable_type = type
我要找的是

以下是一对多关系的示例:

from app import db
from datetime import datetime
from sqlalchemy import event, and_
from sqlalchemy.orm import relationship, foreign, remote, backref


class HasPhotos():
    pass

class Photo(db.Model):
    __tablename__   = 'photos'
    id              = db.Column(db.Integer(), primary_key=True)
    image           = db.Column(db.String())
    photoable_id    = db.Column(db.Integer())
    photoable_type  = db.Column(db.String(50))
    created_at      = db.Column(db.DateTime(), default=datetime.utcnow)
    updated_at      = db.Column(db.DateTime(), default=datetime.utcnow)

    @property
    def parent(self):
        return getattr(self, 'parent_{}'.format(self.photoable_type))



@event.listens_for(HasPhotos, 'mapper_configured', propagate=True)
def setup_listener(mapper, class_):
    name = class_.__name__
    type = name.lower()
    class_.photos = relationship(Photo,
                        primaryjoin=and_(
                                        class_.id == foreign(remote(Photo.photoable_id)),
                                        Photo.photoable_type == type
                                    ),
                        backref=backref(
                                'parent_{}'.format(type),
                                primaryjoin=remote(class_.id) == foreign(Photo.photoable_id)
                                )
                        )
    @event.listens_for(class_.photos, 'append')
    def append_photo(target, value, initiator):
        value.photoable_type = type
然后,当定义一个类来建立这种关系时,只需继承自
hasphots
,例如

class Artist(HasPhotos, db.Model):
    pass
要建立一对一的关系,只需将关键字参数
uselist=False
添加到
relationship()
调用中,而不是侦听
append
事件,而是侦听
set
事件,例如:

@event.listens_for(class_.photo, 'set')
def set_photo(target, value, old_value, initiator):
    value.photoable_type = type