Python SQLAlchemy:将信息传递给自动映射多对多关系
我们正在将一个代码库转换为SqlAlchemy,其中有一个现有的数据库可以修改,但不能完全替换 有一个小部件集合,对于每个小部件,我们跟踪20个最相似的其他小部件(这是一种方向关系,即Python SQLAlchemy:将信息传递给自动映射多对多关系,python,sqlalchemy,flask-sqlalchemy,Python,Sqlalchemy,Flask Sqlalchemy,我们正在将一个代码库转换为SqlAlchemy,其中有一个现有的数据库可以修改,但不能完全替换 有一个小部件集合,对于每个小部件,我们跟踪20个最相似的其他小部件(这是一种方向关系,即widget_2可以出现在widget_1最相似的小部件中,但反之亦然) 有一个widget表,它有一个widget\u id字段和一些其他内容 有一个相似性表,其中有第一个小部件id,第二个小部件id和相似性评分。我们只在数据库中保存20个最相似的小部件,这样每个小部件\u id都会显示为第一个小部件\u id
widget_2
可以出现在widget_1
最相似的小部件中,但反之亦然)
- 有一个
表,它有一个widget
字段和一些其他内容widget\u id
- 有一个
表,其中有相似性
,第一个小部件id
和第二个小部件id
。我们只在数据库中保存20个最相似的小部件,这样每个相似性评分
都会显示为小部件\u id
的20倍第一个小部件\u id
和first\u widget\u id
具有指向second\u widget\u id
表的外键widget
小部件
对象有一个小部件。相似性集合
字段。但是,对于指定的widget\u id
,它只包括second\u widget\u id==widget\u id
的项目,而我们需要first\u widget\u id==widget\u id
。我知道SQLAlchemy无法知道它应该选择这两个选项中的哪一个
我们能说出来吗
编辑:根据评论,以下是有关模型的更多详细信息:
CREATE TABLE IF NOT EXISTS `similarity` (
`first_widget_id` int(6) NOT NULL,
`second_widget_id` int(6) NOT NULL,
`score` int(5) NOT NULL,
PRIMARY KEY (`first_widget_id`,`second_widget_id`),
KEY `first_widget_id` (`first_widget_id`),
KEY `second_widget_id_index` (`second_widget_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER TABLE `similarity`
ADD CONSTRAINT `similar_first_widget_id_to_widgets_foreign_key` FOREIGN KEY (`first_widget_id`) REFERENCES `widgets` (`widget_id`) ON DELETE CASCADE ON UPDATE CASCADE,
ADD CONSTRAINT `similar_second_widget_id_to_widgets_foreign_key` FOREIGN KEY (`second_widget_id`) REFERENCES `widgets` (`widget_id`) ON DELETE CASCADE ON UPDATE CASCADE;
CREATE TABLE IF NOT EXISTS `widgets` (
`widget_id` int(6) NOT NULL AUTO_INCREMENT,
`widget_name` varchar(70) NOT NULL,
PRIMARY KEY (`game_id`),
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=13179 ;
并使用此python代码初始化SQLAlchemy:
base = automap_base()
engine = create_engine(
'mysql://%s:%s@%s/%s?charset=utf8mb4' % (
config.DB_USER, config.DB_PASSWD, config.DB_HOST, config.DB_NAME
), echo=False
)
# reflect the tables
base.prepare(self.engine, reflect=True)
Widgets = base.classes.widgets
现在,当我们做一些类似的事情时:
session.query(Widgets).filter_by(widget_id=1).similarity_collection
我们得到了
sqlalchemy.ext.automap.similous
对象,其第二个小部件id==1
,而我们想要第一个小部件id==1
您可以覆盖相似性集合
的连接方式,即使在自动映射时,也可以通过一个和传递给关系:
base = automap_base()
engine = create_engine(
'mysql://%s:%s@%s/%s?charset=utf8mb4' % (
config.DB_USER, config.DB_PASSWD, config.DB_HOST, config.DB_NAME
), echo=False
)
# The class definition that ensures certain join path for the relationship.
# Rest of the mapping is automapped upon reflecting.
class Widgets(base):
__tablename__ = 'widgets'
similarity_collection = relationship(
'similarity', foreign_keys='similarity.first_widget_id')
base.prepare(self.engine, reflect=True)
如果您还希望控制在
相似性中创建的关系
——对于整洁的关联代理或诸如此类的关系,请使用相同的模式。关于您的模型,您可以更具体一点吗?虽然您自动映射,但可能会创建一个反映您所遇到问题的映射。听起来您可能在寻找关系的param以处理多个连接路径,但我不能确定。已使用所有相关代码更新。希望现在更清楚了。太好了!我没有意识到这样手动帮助automap是可能的。谢谢!