Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to achieve inner join using SQLAlchemy?

How to achieve inner join using SQLAlchemy ? I am trying to make simple chat

class Base(object):
    def __tablename__(self):
        return self.__name__.lower()

    id = Column(Integer, primary_key=True)

Base = declarative_base(cls=Base)

class PlayerModel(Base):
    __tablename__ = 'players'
    username = Column(String(30), nullable=False)
    email = Column(String(75), nullable=False)
    password = Column(String(128), nullable=False)

class MessageModel(Base):
    __tablename__ = 'messages'
    player_id = Column(Integer,ForeignKey('chats.id'), nullable=False)
    message = Column(String(2000), nullable=False)
    time = Column(TIMESTAMP, server_default=func.now())

    def __repr__(self):
        return "<Message('%s')>" % (self.type)

I want to read all messages younger than some date and in result to have list of dictionaries like

[{'username':'x','message':'y','time':'number0'},{'username':'y','message':'z','time':'number1'},
{'username':'x','message':'zz','time':'number'}]

and for that I need inner join. How to make this to work ?

like image 976
PaolaJ. Avatar asked Nov 27 '12 12:11

PaolaJ.


People also ask

How do I join SQLAlchemy?

In this chapter, we will learn how to use Joins in SQLAlchemy. Effect of joining is achieved by just placing two tables in either the columns clause or the where clause of the select() construct. Now we use the join() and outerjoin() methods. The join() method returns a join object from one table object to another.

How do I join two columns in SQLAlchemy?

You can use . join() and then specify the join condition with the second param. If you omit the join condition, then the . query() method alone generates a cross join between table1 and table2.


1 Answers

For that you first need to have a session to make a Query. Additionally it can be convenient to have a relationship on your MessageModel.

class MessageModel(Base):
    __tablename__ = 'messages'
    player_id = Column(Integer,ForeignKey('chats.id'), nullable=False)
    message = Column(String(2000), nullable=False)
    time = Column(TIMESTAMP, server_default=func.now())
    player = relationship(PlayerModel, backref="messages")

This will create the relationship on both models.

results = (session.query(PlayerModel)
                  .join(PlayerModel.messages)
                  .values(PlayerModel.username,
                          MessageModel.message,
                          MessageModel.time))
# results will be a generator object

# This seems a bit convoluted, but here you go.
resultlist = []
for username, message, time in results:
    resultlist.append({'message': message,
                       'username': username,
                       'time': time})

There may be more elegant ways to come to your data structure but this one should work.

like image 70
pi. Avatar answered Nov 14 '22 20:11

pi.