• SQLAlchemy使用说明之ORM


    对象关系映射(Object Relation Map, ORM)可以将一个类映射为关系模式(数据表). 使用ORM比直接书写SQL在安全性,可读性上都有很大优势.

    Working with Related Objects

    下面的示例展示如何使用ORM定义一个关系模式并进行实例化.

    from sqlalchemy import create_engine, Table, Column, Integer, String, MetaData, ForeignKey
    import MySQLdb
    
    from sqlalchemy.orm import sessionmaker
    from sqlalchemy.ext.declarative import declarative_base
    
    Base = declarative_base()
    
    class User(Base):
    	__tablename__ = 'user'
    	user_id = Column('user_id', Integer, primary_key=True)
    	name = Column('name', String(20))
    	fullname = Column('fullname', String(20))
    	
    	def __repr__(self):
    		return "<User(user_id='%d', name='%s'), fullname='%s'>" % (self.user_id, self.name, self.fullname)
    
    def get_session(): 
    	engine = create_engine("mysql://root:248536@localhost:3306/test?charset=utf8", encoding="utf-8", echo=True)
    	mysql_session_maker = sessionmaker(bind=engine)
    	session = mysql_session_maker()
    	return session
         
    if __name__ == '__main__':
    	session = get_session()
        user = User(user_id=1, name='finley', fullname='finley ?')
        session.add(user)
        session.commit()
        user = User(user_id=2, name='finley2', fullname='finley ?')
        session.add(user)
        session.rollback()
        user = User(user_id=3, name='finley3', fullname='finley ?')
        session.add(user)
        session.commit()
        session.close()
    

    终端回显:

    INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
    INFO sqlalchemy.engine.base.Engine INSERT INTO user (user_id, name, fullname) VALUES (%s, %s, %s)
    INFO sqlalchemy.engine.base.Engine (1, 'finley', 'finley ?')
    INFO sqlalchemy.engine.base.Engine COMMIT
    INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
    INFO sqlalchemy.engine.base.Engine INSERT INTO user (user_id, name, fullname) VALUES (%s, %s, %s)
    INFO sqlalchemy.engine.base.Engine (3, 'finley3', 'finley ?')
    INFO sqlalchemy.engine.base.Engine COMMIT
    

    上述示例展示了通过ORM和session进行事务操作(implicit transcation).

    通过metadata创建表:

    Base.metadata.create_all(engine)
    

    rollback()可以回滚到上次commit.

    通过session进行事务性操作, 注意那些复杂的工厂.

    Add & Remove

    生成实例后用session进行添加或者删除操作:

    user = User(user_id=1, name='finley', fullname='finley ?')
    session.add(user)
    session.commit()
    

    删除操作类似, 注意User实例通过查询数据库获得:

    user = session.query(User).filter(User.user_id == 1)[0]
    session.delete(user)
    session.commit()   
    

    Query

    首先做一个全查询:

    result = session.query(User)
    session.commit()
    session.close()
    # print result
    print(result)
    for instance in result:
    	print(instance)
    

    返回的结果:

    INFO sqlalchemy.engine.base.Engine   SELECT 
    user.user_id AS user_user_id, 
    user.name AS user_name, 
    user.fullname AS user_fullname 
    FROM user
    
    INFO sqlalchemy.engine.base.Engine ()
    <User(user_id='1', name='finley'), fullname='finley ?'>
    <User(user_id='3', name='finley3'), fullname='finley ?'>
    

    也可以很方便的指定要查询的列:

    result = session.query(User.user_id, User.name)
    

    结果:

    (1L, u'finley')
    (3L, u'finley3')
    

    ORM使用filter来筛选记录:

    >>> result = session.query(User.user_id, User.name).filter(User.user_id == 1).all()
    >>>session.commit()
    >>>session.close()
    >>>
    >>>print(result) 
    [(1L, u'finley')]
    

    query对象使用和select类似的运算符, filter可以链式调用并支持order_by()等功能.

    更多黑魔法请参见

    Relationship

    Many to One

    Relationship用来维护两个数据表之间的关系, 含有Relationship的表需要使用外键指定参照关系:

    from sqlalchemy import create_engine, Table, Column, Integer, String, MetaData, ForeignKey
    import MySQLdb
    
    from sqlalchemy.orm import sessionmaker
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy.orm import relationship, backref
    
    
    Base = declarative_base()
    
    class User(Base):
    	__tablename__ = 'user'
    	user_id = Column('user_id', Integer, primary_key=True)
    	name = Column('name', String(20))
    	fullname = Column('fullname', String(20))
    	def __repr__(self):
    		return "<User(user_id='%d', name='%s', fullname='%s')>" % (self.user_id, self.name, self.fullname)
    
    class Address(Base):
    	__tablename__ = 'address'
    	address_id = Column('address_id', Integer, primary_key=True)
    	user_id = Column(Integer, ForeignKey('user.user_id'))
    	user = relationship("User", backref=backref('addresses'))
    	def __repr__(self):
    		return "<Address(address_id='%d', user_id='%d')>" % (self.address_id, self.user_id)
    
    def get_session(): 
    	engine = create_engine("mysql://root:248536@localhost:3306/test?charset=utf8", encoding="utf-8", echo=True)
    	mysql_session_maker = sessionmaker(bind=engine)
    	session = mysql_session_maker()
    	return session
    
    
    if __name__ == '__main__':
    	session = get_session()
    	# add by user
    	user = User(user_id=1, name='finley', fullname='finley ?')
    	user.addresses = [
    		Address(address_id=1, user_id=1),
    		Address(address_id=2, user_id=1)
    	]
    	session.add(user);
    	# add by address
    	address = Address(address_id=3, user_id=1)
    	session.add(address)
    	session.commit()
    	# query relationship
    	result = session.query(User).filter(User.user_id == 1)
    	for i in result:
    		print(i.addresses)
    	session.close()
    

    反向索引backref使得User实例可以查询与其关联的address:

    user.addresses
    

    添加关系可以直接操作Address表:

    address = Address(address_id=3, user_id=1)
    session.add(address) # session.remove(address)
    session.commit()
    

    也可以通过User的backref:

        user = User(user_id=1, name='finley', fullname='finley ?')
    	user.addresses = [
    		Address(address_id=1, user_id=1),
    		Address(address_id=2, user_id=1)
    	]
    	session.add(user);
    

    删除操作类似, 不过因为Foreign Key约束的存在, 需要费点事.

    (我不会说自己用删除user记录重新添加的方法的)

    Many to Many

    sqlalchemy docs - ORM - Many to Many Relationship

  • 相关阅读:
    Vue 项目在手机上,当input、时间组件获取焦点后组件变大问题
    关于部分手机whitespace失效问题
    网络安全环境IP纯净
    搭建蜜罐HFish
    windows隐藏某某命令
    mysql密码相关
    在k8s集群部署jenkins遇到的问题
    Mongodb简单的操作
    MongoDB安装
    上机编程认证03
  • 原文地址:https://www.cnblogs.com/Finley/p/5572459.html
Copyright © 2020-2023  润新知