在SQLAlchemy中从集合中删除/添加对象

时间:2015-10-27 15:58:47

标签: python oop database-design sqlalchemy

手头的问题:从组中删除用户并将用户添加到组中 多对一表关系
(许多用户对一个群组)
使用:SQLAlchemy 1.0.9,Python 2.7.9

数据库操作CRUD操作:
1.创建一个组(例如'admin')
2.检索组(使用组名称或ID
3. 更新:
a)更新: add_user 到组('joe'到'admin')
b)更新: remove_user 来自组('bob'来自'编辑')
4.删除组

我是一个新手试图弄脏我的手,但在这里很聪明。 1.我尝试从函数.user中移除Group() update_remove_user而不删除user中的User()。我在Stacks here.sqlalchemy docs中发现了类似于我想要做的事情 2.将用户添加到现有组。现在,该功能正在创建一个组和用户,而不是检索一个组并将用户添加到该组。

model:base.py

class Group(Base):
    __tablename__ = 'groups'

    id = Column(Integer, primary_key=True)
    group_name = Column(String(50), unique=True)
    created_on = Column(DateTime, default=datetime.utcnow)
    modified_on = Column(DateTime, onupdate=datetime.utcnow) #new

    user_id = Column(Integer, ForeignKey('users.id'))
    user = relationship('User', backref='groups')

   def __init__(self, group_name, *args):
       self.group_name = group_name
       self.args = args

    def __repr__(self):
        return "<Group(group_name='%s')>" % (self.group_name)

object.py

def create_group(self, group_name): 
    new_group = Group(group_name)
    self.session.add(new_group)
    self.session.commit()
    return new_group
    print 'this is the new group: ', new_group

def update_group_add_user(self, group_name, user):
    g = self.session.query(Group).\
    filter(Group.group_name == group_name).one()
    if g:
        g.append(user) # append not found
        self.session.commit()

def update_group_remove_user(self, group_name, user):
    remove_user = self.session.query(Group).\
    filter(Group.group_name == group_name).\
    filter(Group.user == user).one()
    if remove_user:
        r = remove_user.user
        print 'test r : ', r
        g = Group() # does not work 
        g.remove(r)
        self.session.commit()

以下建议的更改:
add_user以外的作品在添加到具有多对一关系的SAME组(由Alex表示)时,将user替换为new user。因此添加了“多对多”关系,同样的问题正在发生。用户正在以多对多关系替换另一个用户。

更改反映在已解决问题的工作代码下方的。代码正在为N-N关系工作。

object.py

def update_group_add_user(self, group_name, user):
    g = self.session.query(Group).\
    filter(Group.group_name == group_name).one()
    if g:
        found_name = g.group_name
        g.users = [user] # < replaced with working: g.users.append(user)
        print 'found_name and user: ', found_name, user
        self.session.commit()

def update_group_remove_user(self, group_name, user):
    remove_user = self.session.query(Group).\
    filter(Group.group_name == group_name).one()
    if remove_user:
        remove_user.users = None # < replaced with working remove_user.users.remove(user)
        self.session.commit()

多对多设计:

association_t = Table('group_user_link', Base.metadata,
    Column('group_id', Integer, ForeignKey('groups.id')),
    Column('user_id', Integer, ForeignKey('users.id')))

class Group(Base):
    __tablename__ = 'groups'
    id = Column(Integer, primary_key=True)
    name = Column(String(50), unique=True)
    user = relationship('User', secondary='group_user_link', backref='groups')

    # more...

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    username = Column(String(40), unique=True)
    # more info

1 个答案:

答案 0 :(得分:1)

首先,您确定要创建多对一关系吗?

根据这种关系,一个“组”只能包含一个用户。这与术语“组”相反。我想,你应该创建Many-to-Many关系。

至于你的第一期:

g = self.session.query(Group).\
filter(Group.group_name == group_name).one()
...
g.append(user) # append not found

进行此类查询时,结果是Group类的实例。此实例没有append方法。更改此组用户的正确方法是:

g.user = user

关于第二个问题:

def update_group_remove_user(self, group_name, user):
    remove_user = self.session.query(Group).\
    filter(Group.group_name == group_name).\
    filter(Group.user == user).one()
    if remove_user:
        r = remove_user.user
        print 'test r : ', r
        g = Group() # does not work 
        g.remove(r)
        self.session.commit()

同样,remove_user现在是Group的一个实例(因此,您选择了错误的名称)。

当您尝试g = Group(); g.remove(r)时,您刚刚创建了Group的新实例,并尝试调用不存在的方法。因此,为了从组中删除该用户,您应该:

remove_user.user = None
self.session.commit()