SQLAlchemy muchos a muchos relación y objeto de asociación

Estoy teniendo problemas para configurar una relación simple. Logré que funcionara razonablemente bien con el uso de una tabla de asociación simple, pero quería campos ‘meta’ adicionales, así que estoy estudiando el uso de un patrón de objeto de asociación. (Sí, soy un novato de DB)

from flask.ext.sqlalchemy import SQLAlchemy from flask import Flask import os import re import datetime app = Flask(__name__) basedir = os.path.abspath(os.path.dirname(__file__)) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'data.sqlite') app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = False db = SQLAlchemy(app) class NewsletterInfo(db.Model): __tablename__ = 'newsletter_info' id = db.Column(db.Integer, primary_key = True) user_id = db.Column(db.Integer, db.ForeignKey('users.id')) newsletter_id = db.Column(db.Integer, db.ForeignKey('newsletter.id')) date_added = db.Column(db.DateTime, default=datetime.datetime.now) date_modified = db.Column(db.DateTime, default=datetime.datetime.now) note = db.Column(db.String(140)) class User(db.Model): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) email = db.Column(db.String(128), unique=True) password = db.Column(db.String(128)) date_registered = db.Column(db.DateTime, default=datetime.datetime.now) email_verified = db.Column(db.Boolean, default=False) newsletters = db.relationship('NewsletterInfo') class Newsletter(db.Model): __tablename__ = 'newsletter' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String) category = db.Column(db.String(36)) price = db.Column(db.String) 

Puede ignorar el uso de matraz aquí completamente.

Básicamente quiero que cada usuario pueda rastrear tantos boletines como quieran. Y cada conexión de Usuario >> Boletín tendrá alguna información meta, como cuándo la agregaron por primera vez e incluso una nota opcional.

Recibo este error al intentar hacer “my_user.newsletters.append (my_newsletter)”

  Attempting to flush an item of type  as a member of collection "User.newsletters". Expected an object of type  or a polymorphic subclass of this type. 

Esto funcionó para la tabla original que hice, pero obviamente estoy haciendo algo bastante mal con esta configuración un poco más complicada.

¿Podría alguien ayudarme con la relación que estoy tratando de configurar? También me preocupa que sea una relación mal concebida, por lo que agradecería consejos sobre la configuración de la relación estándar para esto.

El error se debe a que ha establecido una relación con NewsletterInfo , no con Newsletter , por lo que obviamente este es el tipo que la colección espera.

Una asociación de muchos a muchos con metainformación no es infrecuente. Para continuar usándolo como si fuera una relación regular a través de User.newsletters , deberá configurar un proxy de asociación . Echa un vistazo al primer ejemplo. Las partes importantes son estas:

 class User(db.Model): # ... newsletters = association_proxy('user_newsletters', 'newsletter') class NewsletterInfo(db.Model): # ... user = relationship(User, backref=backref("user_newsletters")) newsletter = relationship("Newsletter")