zoukankan      html  css  js  c++  java
  • sqlachemy详解

    实习期老大让我学Python...学了很久了好吗,不过确实对其中的一些原理性的东西还不够深入.

    比如今天要说的sqlachemy,结合网上做些总结吧

    ORM 全称 Object Relational Mapping, 翻译过来叫对象关系映射。简单的说,ORM 将数据库中的表与面向对象语言中的类建立了一种对应关系。这样,我们要操作数据库,数据库中的表或者表中的一条记录就可以直接通过操作类或者类实例来完成。
    1.安装
    sudo pip install sqlalchemy

    2.建数据库和数据表
    # coding: utf-8

    from sqlalchemy import create_engine
    from sqlalchemy.ext.declarative import declarative_base
    from sqlalchemy import Column, String, Integer
    from sqlalchemy.orm import sessionmaker


    # 链接数据库采用mysqldb模块做映射
    engine = create_engine('mysql+mysqldb://root:mysql@localhost:3306/blog?charset=utf8')
    # 创建对象的基类:
    Base = declarative_base()

    # 定义User对象:
    class User(Base):
    # 表名
    __tablename__ = 'users'
    # 表结构
    # Column代表数据库中的一列,nullable=False代表这一列不可以为空,index=True表示在该列创建索引
    id = Column(Integer, primary_key=True)
    username = Column(String(64), nullable=False, index=True)
    password = Column(String(64), nullable=False)
    email = Column(String(64), nullable=False, index=True)

    # __repr__ 方便调试,可以不定义
    def __repr__(self):
    return '%s(%r)' % (self.__class__.__name__, self.username)


    # 执行建表命令
    if __name__ == '__main__':
    Base.metadata.create_all(engine)


    3.关系演示
    3.1 一对多关系

    对于一个普通的博客应用来说,用户和文章显然是一个一对多的关系,一篇文章属于一个用户,一个用户可以写很多篇文章,那么他们之间的关系可以这样定义:

    class User(Base):

    __tablename__ = 'users'

    id = Column(Integer, primary_key=True)
    username = Column(String(64), nullable=False, index=True)
    password = Column(String(64), nullable=False)
    email = Column(String(64), nullable=False, index=True)
    articles = relationship('Article')

    def __repr__(self):
    return '%s(%r)' % (self.__class__.__name__, self.username)


    class Article(Base):

    __tablename__ = 'articles'

    id = Column(Integer, primary_key=True)
    title = Column(String(255), nullable=False, index=True)
    content = Column(Text)
    user_id = Column(Integer, ForeignKey('users.id'))
    author = relationship('User')

    def __repr__(self):
    return '%s(%r)' % (self.__class__.__name__, self.title)
    每篇文章有一个外键指向 users 表中的主键 id, 而在 User 中使用 SQLAlchemy 提供的 relationship 描述 关系。而用户与文章的之间的这个关系是双向的,所以我们看到上面的两张表中都定义了 relationship。

    SQLAlchemy 提供了 backref 让我们可以只需要定义一个关系:

    articles = relationship('Article', backref='author')
    添加了这个就可以不用再在 Article 中定义 relationship 了!

    3.2 一对一关系

    在 User 中我们只定义了几个必须的字段, 但通常用户还有很多其他信息,但这些信息可能不是必须填写的,我们可以把它们放到另一张 UserInfo 表中,这样User 和 UserInfo 就形成了一对一的关系。你可能会奇怪一对一关系为什么不在一对多关系前面?那是因为一对一关系是基于一对多定义的:

    class User(Base):

    __tablename__ = 'users'

    id = Column(Integer, primary_key=True)
    username = Column(String(64), nullable=False, index=True)
    password = Column(String(64), nullable=False)
    email = Column(String(64), nullable=False, index=True)
    articles = relationship('Article', backref='author')
    userinfo = relationship('UserInfo', backref='user', uselist=False)

    def __repr__(self):
    return '%s(%r)' % (self.__class__.__name__, self.username)


    class UserInfo(Base):

    __tablename__ = 'userinfos'

    id = Column(Integer, primary_key=True)
    name = Column(String(64))
    qq = Column(String(11))
    phone = Column(String(11))
    link = Column(String(64))
    user_id = Column(Integer, ForeignKey('users.id'))
    定义方法和一对多相同,只是需要添加 userlist=False 。


    3.3 多对多关系

    一遍博客通常有一个分类,好几个标签。标签与博客之间就是一个多对多的关系。多对多关系不能直接定义,需要分解成俩个一对多的关系,为此,需要一张额外的表来协助完成:

    article_tag = Table(
    'article_tag', Base.metadata,
    Column('article_id', Integer, ForeignKey('articles.id')),
    Column('tag_id', Integer, ForeignKey('tags.id'))
    )


    class Tag(Base):

    __tablename__ = 'tags'

    id = Column(Integer, primary_key=True)
    name = Column(String(64), nullable=False, index=True)

    def __repr__(self):
    return '%s(%r)' % (self.__class__.__name__, self.name)


    4.增删改查

    要完成数据库查询,就需要建立与数据库的连接。这就需要用到Engine对象。一个Engine可能是关联一个Session对象,也可能关联一个数据库表。
    当然Session最重要的功能还是实现原子操作。

    你可以把 sessionmaker 想象成一个手机,engine 当做 MySQL 的号码,拨通这个“号码”我们就创建了一个 Session 类,下面就可以通过这个类的实例与 MySQL 愉快的交谈了

    create_engine() 会返回一个数据库引擎,echo 参数为 True 时,会显示每条执行的 SQL 语句,生产环境下可关闭。sessionmaker() 会生成一个数据库会话类。这个类的实例可以当成一个数据库连接,它同时还记录了一些查询的数据,并决定什么时候执行 SQL 语句。

    from sqlalchemy import create_engine 

    from sqlalchemy.orm import sessionmaker

    some_engine = create_engine('nysql://username:password@localhost/mydb?charset=utf8')
    # 创建Session类型:
    Session = sessionmaker(bind=some_engine)
    # 创建session对象:
    session = Session()

    4.1增

    # 创建新User对象:
    new_user = User(id='5', name='Bob')
    # 添加到session:
    session.add(new_user)
    # 提交即保存到数据库:
    session.commit()
    # 关闭session:
    session.close()

    4.2查
    # 创建Query查询,filter是where条件,最后调用one()返回唯一行,如果调用all()则返回所有行:
    user = session.query(User).filter(User.id=='5').one()
    # 打印类型和对象的name属性:
    print('type:', type(user))
    print('name:', user.name)
    # 关闭Session:
    session.close()

    4.3更新
    user = session.query(User).filter_by(name="user1").first()
    user.password = "newpassword"
    session.commit()
    session.close()

    4.4删
    user = session.query(User).filter_by(name="user1").first()
    session.delete(user)
    session.commit()
    session.close()

    关键,有pymsql为什么还需要sqlachemy
    ==>如何从数据库表中查询数据呢?有了ORM,查询出来的可以不再是tuple,而是User对象

    排版什么的以后再改,学无止境 

  • 相关阅读:
    异常处理 Exception
    C#使用SQLite出错:无法加载 DLL“SQLite.Interop.dll”,找不到指定的模块
    NullableKey:解决Dictionary中键不能为null的问题 zt
    STSdb
    C# 如何获取某个类型或类型实例对象的大小
    CORREL
    C# 深复制
    mysql数据库创建函数过程
    mysql 数据库怎样快速的复制表以及表中的数据
    代码优化(一)
  • 原文地址:https://www.cnblogs.com/giotto95827/p/8662507.html
Copyright © 2011-2022 走看看