2014-01-22 11 views
9

Basierend auf einigen Stellen auf der SQLAlchemy Google-Gruppe:Wie richtig nutzen association_proxy und ordering_list zusammen mit SQLAlchemy

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

Ich nahm ich erfolgreich die assocation_proxy und ordering_list Erweiterungen verwenden könnte eine geordnete zu schaffen, viele zu viel Beziehung zwischen zwei Modellen wie in dem folgenden Flask/SQLAlchemy Code:

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() 

Aber ich am Ende w its die folgende Rückverfolgung:

$ 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) 

Ist das nicht möglich oder mache ich etwas eklatant falsch?

Antwort

15

sooo nah ;-)

Bitte lesen Sie Creation of New Values secion von association_proxy Erweiterung.
Um Ihren Code Arbeit zu machen, können Sie entweder

Option-1: den folgenden Konstruktor zu UserImage Klasse hinzufügen:

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

oder

Option-2: Überschreibung der Standard creator mit Ihrer Funktion:

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

Ich persönlich bevorzuge Letzteres.

Verwandte Themen