2014-01-22 64 views
9

基於對SQLAlchemy的谷歌集團的一些職位如何正確使用association_proxy和ordering_list:連同SQLAlchemy的

https://groups.google.com/forum/#!topic/sqlalchemy/S4_8PeRBNJw https://groups.google.com/forum/#!topic/sqlalchemy/YRyI7ic1QkY

我認爲我能成功地使用assocation_proxyordering_list擴展創造一個有序,許多人,如在以下瓶/ SQLAlchemy的代碼兩種模式之間一對多的關係:

from flask import Flask 
from flask_sqlalchemy import SQLAlchemy 
from sqlalchemy.ext.associationproxy import association_proxy 
from sqlalchemy.ext.orderinglist import ordering_list 

app = Flask(__name__) 
app.debug = True 
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite://' 
db = SQLAlchemy(app) 


class Image(db.Model): 
    __tablename__ = 'images' 

    id = db.Column(db.Integer, primary_key=True) 
    filename = db.Column(db.String(255)) 


class UserImage(db.Model): 
    __tablename__ = 'user_images' 

    user_id = db.Column(db.Integer, db.ForeignKey('users.id'), primary_key=True) 
    image_id = db.Column(db.Integer, db.ForeignKey('images.id'), primary_key=True) 
    image = db.relationship('Image') 
    position = db.Column(db.Integer) 


class User(db.Model): 
    __tablename__ = "users" 

    id = db.Column(db.Integer, primary_key=True) 
    name = db.Column(db.String(255)) 

    _images = db.relationship('UserImage', 
     order_by='UserImage.position', 
     collection_class=ordering_list('position')) 
    images = association_proxy('_images', 'image') 


with app.app_context(): 
    db.create_all() 
    user = User(name='Matt') 
    user.images.append(Image(filename='avatar.png')) 
    db.session.add(user) 
    db.session.commit() 

if __name__ == '__main__': 
    app.run() 

但我最終瓦特ith以下追溯:

$ python app.py 
Traceback (most recent call last): 
    File "app.py", line 44, in <module> 
    user.images.append(Image(filename='avatar.png')) 
    File "/Users/matt/.virtualenvs/sqlalchemy-temp/lib/python2.7/site-packages/sqlalchemy/ext/associationproxy.py", line 595, in append 
    item = self._create(value) 
    File "/Users/matt/.virtualenvs/sqlalchemy-temp/lib/python2.7/site-packages/sqlalchemy/ext/associationproxy.py", line 522, in _create 
    return self.creator(value) 
TypeError: __init__() takes exactly 1 argument (2 given) 

這是不可能的,或者我在做一些明顯的錯誤?

回答

15

SOOO接近;-)

請仔細閱讀Creation of New Values secion association_proxy延伸。
爲了使你的代碼的工作,您可以

選項-1:添加下面的構造方法UserImage類:

def __init__(self, image): 
    self.image = image 

選項-2:覆蓋默認creator與您的功能:

images = association_proxy('_images', 'image', 
    creator=lambda _i: UserImage(image=_i), 
    ) 

我個人比較喜歡後者。