2010-02-04 7 views
1

많은 다형성 SQLAlchemy의 내 웹 응용 프로그램에서 사용자에게 '좋아하는'다른 항목 수 있도록 노력하고있어. 따라서 예를 들어 사용자는 댓글을 선호하고 뉴스를 좋아할 수 있습니다. 그런 다음 사용자가 선호하는 모든 항목을 쿼리하고 관련 객체 (뉴스 기사 또는 주석이든)를 다형성으로로드하여 객체 목록을 사용자에게 표시하려고합니다. 나는 일대일 다형성 관계를 만드는 방법을 알고 있지만, 많은 것을 알아낼 수는 없습니다. 사전에많은 관계

감사

편집

내 일대일 다형성의 관계에서

나는 사용자 및 사용자의 행동 사이에 한 많은 관계를 가지고 있고, 사용자 작업과 사이에 일대일 다형성의 관계 액션이 수행 된 객체. 따라서이 경우에는 내 사용자 작업 테이블과 같이이다 :

class UserAction: 
    pass 

user_actions = Table('user_action', metadata, 
    Column('id', Integer, autoincrement=True, primary_key=True), 
    Column('module', String(30)), 
    Column('created', DateTime, default=datetime.now), 
    Column('user_id', Integer, ForeignKey('user.id')) 
) 

뉴스 테이블 (사용자 동작을 통해 액세스 할 수있는 개체 중 하나) :

class News: 
    pass 

news = Table('news', metadata, 
    Column('id', Integer, autoincrement=True, primary_key=True), 
    Column('title', String(30), nullable=False), 
    Column('action_id', Integer, ForeignKey('user_action.id')) 
) 

그리고 매퍼 :

mapper(UserAction, user_actions, polymorphic_on=user_actions.c.module, polymorphic_identity='user_action') 
mapper(News, news, inherits=UserAction, polymorphic_identity='news') 

당신이 볼 수 있듯이, 뉴스 객체와 그와 관련된 USER_ACTION 기록 사이에 명확한 일대일 관계가있다. user_action 외래 키가 뉴스 테이블에 있기 때문입니다. 많은 사용자가 여러 개의 다른 객체 유형을 선호 할 수있는 다형성 관계를 만드는 방법을 찾고자한다면 어떻게해야할까요? 정말 고마워.

+0

다형성 모델과 다 대다 관계를 일대일로 만드는 데 차이가 없습니다. 좀 더 정확하거나 작동하지 않거나 적응하기 원하는 코드 샘플을 게시 할 수 있습니까? –

답변

2

귀하의 예는 UserActionNews 사이에 일대 다 관계를 정의합니다. 내가 이유를 볼 수 없기 때문에 나에게 혼란처럼 보이는 이유 UserAction에서 News 상속합니다. 한 다스를 UserAction 및 다른 News에 : 당신은 하나의 뉴스를 다스 려 여러 사용자 동작은 두 개의 외래 키와 중간 테이블을 정의 할 수 있도록합니다.

  1. 각 favourited 모델 클래스를 사용하여 별도의 중간 테이블을 각 UserAction 서브 클래스에서 다른 관계를 정의 : 나는 다형성 만드는 두 합리적인 방법을 참조하십시오.
  2. 중간 테이블에서 각 선호 모델에 대해 별도의 외래 키를 정의하고 단일 테이블 상속을 사용하여 클래스 계층에 매핑합니다 (UserActionItem, UserActionNewsItem 등). 그 무엇보다도

그러나 참고, 다 대다 관계로 UserAction 일부 항목 모델 연결을위한 것입니다. 사용자가 항목을 채우는 것은 더 이상 User을 엔트리 모델과 연결하는 것과 같습니다.

업데이트 : 아래 예를 노력하고 있습니다. 내가 볼 수있는 유일한 문제는 그것이 중복을 허용한다는 것입니다.

from sqlalchemy import * 
from sqlalchemy.orm import mapper, relation, sessionmaker 
from sqlalchemy.ext.associationproxy import association_proxy 

metadata = MetaData() 

users = Table(
    'users', metadata, 
    Column('id', Integer, nullable=False, primary_key=True), 
) 

news = Table(
    'news', metadata, 
    Column('id', Integer, nullable=False, primary_key=True), 
) 

comments = Table(
    'comments', metadata, 
    Column('id', Integer, nullable=False, primary_key=True), 
) 

favitems = Table(
    'favitems', metadata, 
    Column('id', Integer, nullable=False, primary_key=True), 
    Column('user_id', Integer, ForeignKey(users.c.id), nullable=False), 
    Column('item_type', Integer, nullable=False), 
    Column('news_id', Integer, ForeignKey(news.c.id)), 
    Column('comment_id', Integer, ForeignKey(comments.c.id)), 
) 

class News(object): pass 

class Comment(object): pass 

class FavItem(object): 
    TYPE_NEWS = 1 
    TYPE_COMMENT = 2 
    def __new__(cls, item=None): 
     if isinstance(item, News): 
      cls = FavNews 
     elif isinstance(item, Comment): 
      cls = FavComment 
     return object.__new__(cls) 

class FavNews(FavItem): 
    def __init__(self, item): 
     self.item_type = self.TYPE_NEWS 
     self.item = item 

class FavComment(FavItem): 
    def __init__(self, item): 
     self.item_type = self.TYPE_COMMENT 
     self.item = item 

class User(object): 
    favorites = association_proxy('_favitems', 'item', creator=FavItem) 

mapper(News, news) 

mapper(Comment, comments) 

mapper(FavItem, favitems, 
     polymorphic_on=favitems.c.item_type) 

mapper(FavNews, favitems, 
     inherits=FavItem, 
     polymorphic_identity=FavItem.TYPE_NEWS, 
     properties={ 
      'item': relation(News), 
     }) 

mapper(FavComment, favitems, 
     inherits=FavItem, 
     polymorphic_identity=FavItem.TYPE_COMMENT, 
     properties={ 
      'item': relation(Comment), 
     }) 

mapper(User, users, 
     properties={ 
      '_favitems': relation(FavItem), 
     }) 

engine = create_engine('sqlite://') 
metadata.create_all(engine) 
session = sessionmaker(engine)() 

user = User() 
news1 = News() 
news2 = News() 
comment1 = Comment() 
comment2 = Comment() 
user.favorites = [news1, news2, comment1, comment2] 
session.add(user) 
session.commit() 
user_id = user.id 

session.expunge_all() 
user = session.query(User).get(user_id) 
print user.favorites 
+0

응답 해 주셔서 감사합니다. 나는 당신이 무엇을 얻고 있는지 이해하고 있다고 생각하지만 그것을 구현하는 방법을 잘 모른다. 위에서 제시 한 모델을 조정하여 좀 더 구체적인 예를 들어 주시겠습니까?user_action 테이블에 뉴스와 주석이 다형성 인 user_action 테이블, 뉴스 테이블 및 주석 테이블이 있다고 가정 해 보겠습니다. 테이블과 매퍼는 어떻게 작동합니까? 매우 감사합니다. – Marc