在不实际创建外键的情况下定义关系

时间:2015-02-23 10:50:29

标签: python sqlalchemy

我有一个表,我已将MySQL引擎从MyISAM更改为InnoDB。这是唯一一个已更改的表,与之相关的表仍然使用MyISAM。

class Signals(Base, sql_functions):
    __tablename__ = 'Signals'

    def __init__(self, message_id=None, clip_id=None, signal_id=None):
        self.message_id = message_id
        self.clip_id = clip_id
        self.signal_id = signal_id

    __table_args__ = {  
        'mysql_engine': 'InnoDB',  
        'mysql_charset': 'utf8'  
    }

    __mapper_args__= {'always_refresh': True}

    id = Column(Integer(10), primary_key=True)
    message_id = Column(Integer(10), ForeignKey('Messages.id'))
    clip_id = Column(Integer(10), ForeignKey('Clips.id'))
    signal_id = Column(Integer(10), ForeignKey('Signal_names.id'), primary_key=True)

    sig_name = relationship("SignalNames", backref=backref('Signals', order_by=id), primaryjoin = 'Signals.signal_id == SignalNames.id', foreign_keys='SignalNames.id')
    clips = relationship("Clips", backref=backref('Signals', order_by=id), primaryjoin='Signals.clip_id == Clips.id', foreign_keys='Clips.id')
    messages = relationship("Messages", backref=backref('Signals', order_by=id), primaryjoin='Signals.message_id == Messages.id', foreign_keys='Messages.id')

    def __repr__(self):
        return "<Signals ('%s %s %s')>" % (self.message_id, self.clip_id)

    Index('idx_msg_id', Signals.message_id)

由于我已将Engine更改为InnoDB,因此正在创建外键,这是不可取的。问题是SQLAlchemy使用外键定义来定义关系连接。

有没有办法防止创建外键,或者在没有添加外键的情况下定义关系?

2 个答案:

答案 0 :(得分:1)

创建关系时,SQLAlchemy使用ForeignKey来检测要加入的列。你当然可以override that with whatever join condition you want。您几乎已经这样做了,您只需要从每列中删除ForeignKey并正确定义每个关系的外来列。

signal_id = Column(Integer(10), primary_key=True)

sig_name = relationship(
    'SignalNames',
    primaryjoin='Signals.signal_id == SignalNames.id',
    foreign_keys='Signals.signal_id',
    remote_side='SignalNames.id',
)

但是,通常,您希望使用外键。

答案 1 :(得分:0)

我从另一个论坛得到了解决方案 -

而不是     join(clips_table.Clips) 我用过     join(signals_table.Signals.clips)