2014-02-27 47 views
0

我试图添加属性到我的模型中的多对多关系,现在当我加载一个对象时,我只从我的查询中获取一个相关对象。为什么SQLAlchemy只从我的多对多关系中加载一个实例?

具体而言,我试图获取与给定备份关联的所有应用程序,以及BackupApp.status列。

对不起,信息转储:

The code is here

我知道我有几百个关系到负载:

$ 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 
+0

谢谢你的标签修复,查尔斯。 –

回答

1

好了,所以这里发生了什么事:

当我第一次提出的backups_apps表,我没有使用CRUDMixin所以它没有一个id列。当我将ID列迁移时,所有的值都初始化为0.SQLAlchemy悄悄地忽略了具有相同ID的所有多行。

+0

+1分享你的调查,好风格 – knitti

相关问题