Python 为什么SQLAlchemy只从我的多对多关系中加载一个实例?
我试图在模型中向多对多关系添加属性,现在当我加载一个对象时,我从查询中只得到一个相关对象 具体来说,我正在尝试获取与给定备份关联的所有应用程序,以及BackupApp.status列 抱歉,信息转储: : 我知道我要加载数百个关系:Python 为什么SQLAlchemy只从我的多对多关系中加载一个实例?,python,sqlalchemy,flask-sqlalchemy,Python,Sqlalchemy,Flask Sqlalchemy,我试图在模型中向多对多关系添加属性,现在当我加载一个对象时,我从查询中只得到一个相关对象 具体来说,我正在尝试获取与给定备份关联的所有应用程序,以及BackupApp.status列 抱歉,信息转储: : 我知道我要加载数百个关系: $ sqlite3 dev.db "select count(*) from backups_apps where backup_id = 3 and app_id is not null;" 415 但我只得到一个: { "children": [
$ sqlite3 dev.db "select count(*) from backups_apps where backup_id = 3 and app_id is not null;"
415
但我只得到一个:
{
"children": [
{
"children": [
{
"bundle_id": "com.iojoe.10",
"compressed": 13151750,
"name": "10",
"size": 14458882
}
],
"name": "Games"
}
],
"name": "root"
}
模型:
# -*- coding: utf-8 -*-
from app_sizer.database import db, CRUDMixin, TimestampMixin, jsonify_plist
from sqlalchemy.ext.associationproxy import association_proxy
class App(db.Model, CRUDMixin, TimestampMixin):
__tablename__ = 'apps'
bundle_id = db.Column(db.String, unique=True, index=True)
app_id = db.Column(db.Integer, unique=True, index=True)
path = db.Column(db.String, unique=True, index=True)
name = db.Column(db.String, index=True)
main_genre = db.Column(db.String, index=True)
compressed_size = db.Column(db.Integer)
full_size = db.Column(db.Integer)
plist = db.Column(db.PickleType)
plist_json = db.Column(db.Text, default=jsonify_plist, onupdate=jsonify_plist)
subgenre_1 = db.Column(db.String, index=True)
subgenre_2 = db.Column(db.String, index=True)
@classmethod
def get_by_bundle_id(cls, bundle_id):
return db.session.query(cls).filter(App.bundle_id == bundle_id).first()
@classmethod
def get_by_path(cls, path):
return db.session.query(cls).filter(App.path == path).first()
@classmethod
def get_all(cls):
return db.session.query(cls).all()
"""
class AppTag(CRUDMixin):
app_id = db.Column(db.Integer, foreign_key='app.id')
user_id = db.Column(db.Integer, foreign_key='user.id')
tag = db.Column(db.String)
"""
# db.Index('idx_tag_user', 'app_tag.user_id', 'app_tag.tag')
class Backup(db.Model, CRUDMixin, TimestampMixin):
__tablename__ = 'backups'
path = db.Column(db.String, unique=True)
name = db.Column(db.String)
notes = db.Column(db.Text)
# Springboard plist
plist = db.Column(db.PickleType)
plist_json = db.Column(db.Text, default=jsonify_plist, onupdate=jsonify_plist)
@classmethod
def get_by_path(cls, path):
return db.session.query(Backup).filter(Backup.path == path).first()
@classmethod
def get_all(cls):
return db.session.query(Backup).all()
# Why does this work but a declarative class doesn't? No idea.
# http://xsnippet.org/359350/
# http://stackoverflow.com/q/5756559/25625
class BackupApp(db.Model, CRUDMixin):
__tablename__ = 'backups_apps'
backup_id = db.Column(db.Integer, db.ForeignKey('backups.id'), nullable=False, default=1)
app_id = db.Column(db.Integer, db.ForeignKey('apps.id'), nullable=False, default=1)
status = db.Column(db.String)
app = db.relationship(App, backref="installed_apps")
backup = db.relationship(Backup, backref="installed_apps")
def __init__(self, app=None, backup=None, status=None):
self.app = app
self.backup = backup
self.status = status
Backup.apps = association_proxy("installed_apps", "app")
App.backups = association_proxy("installed_apps", "backup")
行动:
@blueprint.route("/backup/<int:backup_id>/apps.json")
def apps_json_for_backup(backup_id):
print "in apps_json_for_backup({})".format(backup_id)
backup = Backup.get_by_id(backup_id)
root = to_treemap(backup.apps)
return jsonify(root)
def to_treemap(apps):
root = {"name": "root", "children": list()}
genres = dict()
for app in apps:
if app.main_genre not in genres:
genres[app.main_genre] = list()
leaf = dict(name=app.name, size=app.full_size, compressed=app.compressed_size, bundle_id=app.bundle_id)
genres[app.main_genre].append(leaf)
for genre, leaves in genres.items():
root['children'].append(dict(name=genre, children=leaves))
return root
@blueprint.route(“/backup//apps.json”)
用于备份的def apps_json_(备份id):
打印“用于备份({})的应用程序中的json”。格式(备份id)
backup=backup.get\u by\u id(backup\u id)
root=to_treemap(backup.apps)
返回jsonify(root)
def到_树映射(应用程序):
root={“name”:“root”,“children”:list()}
类型=dict()
对于应用中的应用:
如果app.main_流派不在流派中:
流派[应用程序主流派]=列表()
leaf=dict(name=app.name,size=app.full\u size,compressed=app.compressed\u size,bundle\u id=app.bundle\u id)
流派[app.main\u流派].追加(叶)
对于流派,在genres.items()中留下:
根['children'].append(dict(name=genre,children=leaves))
返回根
好的,下面是发生的情况:
当我第一次创建backups\u apps表时,我没有使用CRUDMixin,所以它没有id列。在中迁移ID列时,所有值都初始化为0。SQLAlchemy悄悄地忽略了所有具有相同id的多行。感谢您的标记修复,Charles。