2015-01-17 5 views
0

У меня возникли проблемы с настройкой простой связи. Мне удалось заставить его работать достаточно хорошо с использованием простой таблицы связей, но мне нужны дополнительные поля «meta», поэтому я изучаю использование шаблона объекта ассоциации. (Да, я новичок в DB)SQLAlchemy для многих отношений и объекта ассоциации

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) 

Вы можете полностью игнорировать использование колбы.

Я в основном хочу, чтобы каждый пользователь мог отслеживать как можно больше информационных бюллетеней. И каждое подключение для пользователя >> Newsletter будет иметь некоторую метаинформацию, например, когда они впервые добавили ее и даже дополнительную заметку.

Я получаю эту ошибку при попытке сделать «my_user.newsletters.append (my_newsletter)»

Attempting to flush an item of type <class 'Newsletter'> as a member of collection "User.newsletters". Expected an 
object of type <class 'NewsletterInfo'> or a polymorphic subclass of this type. 

Это работает для исходной таблицы, который я сделал, но очевидно, что я делаю что-то совершенно неправильно с этим немного больше сложная настройка.

Может ли кто-нибудь помочь мне с отношениями, которые я пытаюсь настроить? Я также обеспокоен тем, что это плохо продуманные отношения, поэтому я бы очень хотел получить совет по установлению стандартных отношений для этого.

+0

Это поможет избавиться от всего этого материала «Flask» и написать собственный пример с использованием 'sqlalchemy' напрямую. Всегда лучше делать примеры как можно меньше. – DanielSank

ответ

3

Ошибка в том, что вы установили связь с NewsletterInfo, а не Newsletter, так что это, очевидно, тот тип, который ожидает коллекция.

Ассоциация многих из многих с метаинформацией не является чем-то необычным. Чтобы продолжить использовать его, как если бы это было регулярное отношение через User.newsletters, вам нужно будет установить association proxy. Посмотрите на первый пример. Важными являются следующие детали:

class User(db.Model): 
    # ... 
    newsletters = association_proxy('user_newsletters', 'newsletter') 

class NewsletterInfo(db.Model): 
    # ... 
    user = relationship(User, backref=backref("user_newsletters")) 
    newsletter = relationship("Newsletter") 
+0

Благодарим вас за помощь. Должен ли я делать что-то другое, чтобы добавлять информационные бюллетени пользователям? Сейчас у меня возникают проблемы, и я замечаю из документации: «требует, чтобы дочерние объекты были связаны с экземпляром ассоциации перед добавлением к родительскому» – Jay

Смежные вопросы