python基础之ORM

官网:https://docs.sqlalchemy.org/en/14/search.html?q=create_engine&check_keywords=yes&area=default

 

ORM:ORM操作是所有完整软件中后端处理最重要的一部分,主要完成了后端程序和数据库之间的数据同步和持久化操作。把关系数据库的表结构映射到对象上,就是ORM框架所做的事。目前来说也是描述程序中对象和数据库中数据记录之间的映射关系的统称,是一种进行程序和数据之间数据持久化的一种编程思想。

SQLAlchemy是Python编程语言下的一款ORM框架,该框架建立在数据库API之上,使用关系对象映射进行数据库操作,简言之便是:将对象转换成SQL,然后使用数据API执行SQL并获取执行结果。ORM框架的作用就是把数据库表的一行记录与一个对象互相做自动转换。

创建表

 

注:create_engine()用来初始化数据库连接。SQLAlchemy用一个字符串表示连接信息:

'数据库类型+数据库驱动名称://用户名:口令@机器地址:端口号/数据库名'

# coding:utf8
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String #区分大小写

# 创建连接
engine = create_engine("mysql+pymysql://root:123456@localhost/ceshi", encoding='utf-8', echo=True)

# 生成orm基类
base = declarative_base()


class user(base):
    # 表名
    __tablename__ = 'users' 
    id = Column(Integer, primary_key=True)
    name = Column(String(32))
    password = Column(String(64))


# 创建表结构
base.metadata.create_all(engine)

执行成功后,可登录数据库查看到users表已经创建成功。

插入数据

关键是获取session,然后把对象添加到session,最后提交并关闭。Session对象可视为当前数据库连接。

# 创建与数据库的会话,class, 不是实例
Session_class = sessionmaker(bind=engine)
# 生成session实例
Session = Session_class()
# coding:utf-8
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import sessionmaker

# 创建连接
engine = create_engine("mysql+pymysql://root:123456@localhost/ceshi", encoding='utf-8', echo=True)
# 生成orm基类
base = declarative_base()


class user(base):
    __tablename__ = 'users' # 表名
    id = Column(Integer, primary_key=True)
    name = Column(String(32))
    password = Column(String(64))


# base.metadata.create_all(engine) #创建表结构

# 创建与数据库的会话,class, 不是实例
Session_class = sessionmaker(bind=engine)
# 生成session实例
Session = Session_class()

# 插入你要创建的数据对象,每执行一次都会新增一次数据。
user_obj = user(name="rr", password="123456")

# 此时还没创建对象呢,不信你打印一下id发现还是None
print user_obj.name, user_obj.id

# 把要创建的数据对象添加到这个session里
Session.add(user_obj)

# 此时也依然还没创建
print user_obj.name, user_obj.id
# 提交,使前面修改的数据生效。
Session.commit()

查询数据

# 接上
# 创建查询对象
my_user = Session.query(user).filter_by(name="rr").first()
# 输出查询内容
print(my_user.id, my_user.name, my_user.password)
# 内存地址
print my_user  

修改数据

# 根据指定条件创建符合条件的对象
my_user = Session.query(user).filter_by(name="rr").first() 
# 将name='rr'的name修改为uu
my_user.name = 'uu' 
Session.commit()
print(my_user.id, my_user.name, my_user.password)  # 输出查询内容

外键关联

# coding:utf-8
from sqlalchemy import create_engine, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import sessionmaker, relationship

# 创建连接
engine = create_engine("mysql+pymysql://root:123456@localhost/ceshi", encoding='utf-8', echo=True)
# 生成orm基类
base = declarative_base()


class user(base):
    __tablename__ = 'users' # 表名
    id = Column(Integer, primary_key=True)
    name = Column(String(32))
    password = Column(String(64))


class Address(base):
    __tablename__ = 'addresses'
    id = Column(Integer, primary_key=True)
    email_address = Column(String(32), nullable=False)
    user_id = Column(Integer, ForeignKey('users.id'))
    user = relationship("user", backref="addresses")
    '''允许你在user表里通过backref字段反向查出所有它在addresses表里的关联项,在内存中创建。在addresses表中可以使用user来查询users表中的数据,在users表中可以使用backref后的addresses来查询assresses表中的数据。'''

    def __repr__(self):
        return "<Address(email_address='%s',id='%d',user_id='%d')>" % (self.email_address, self.id, self.user_id)
# base.metadata.create_all(engine) #创建表结构


# 创建与数据库的会话,class, 不是实例
Session_class = sessionmaker(bind=engine)
# 生成session实例
Session = Session_class()

address_obj = Address(email_address="rrrrr", user_id="1")

# 把要创建的数据对象添加到这个session里
Session.add(address_obj)

# 提交,使前面修改的数据生效。
Session.commit()
# 此时也依然还没创建
print address_obj.email_address, address_obj.id, address_obj.user_id


项目中用到的ORM的基类:

#!/usr/bin/env python
# coding=utf-8

from sqlalchemy import create_engine, MetaData
from sqlalchemy.orm import sessionmaker, scoped_session
from sqlalchemy.orm import mapper
from orm import User

MASTER_DB_USERNAME = 'root'
MASTER_DB_PASSWORD = '123456'
MASTER_DB_HOST = '127.0.0.1'
MASTER_DB_PORT = 3306
MASTER_DB_DBNAME = 'test'


class DBEngine(object):
    def __init__(self, conn_config):
        self.conn_config = conn_config
        self._engine = create_engine(conn_config, pool_size=12, pool_recycle=3500, pool_timeout=600)
        self._metadata = MetaData(self._engine)
        self._metadata.reflect()
        self._tables = self._metadata.tables
        self._classes = {}

        self._Session = sessionmaker(bind=self._engine, expire_on_commit=False)
        self._Scoped_Session = scoped_session(sessionmaker(bind=self._engine, expire_on_commit=False))

    @staticmethod
    def instance():
        if not hasattr(DBEngine, '_instance'):
            conn_config = 'mysql://%s:%s@%s:%s/%s?charset=%s' % (
                        MASTER_DB_USERNAME, MASTER_DB_PASSWORD,
                        MASTER_DB_HOST, MASTER_DB_PORT,
                        MASTER_DB_DBNAME, 'utf8')
#            print conn_config
            DBEngine._instance = DBEngine(conn_config)
        return DBEngine._instance

    def mapper(self, name,  newcls):
        if name in self._tables:
            mapper(newcls, self._tables[name])
        else:
            return newcls

    def get_session(self):
        return self._Session()

    def get_scoped_session(self):
        return self._Scoped_Session()


def get_session():
    engine = DBEngine.instance()
    return engine.get_session()


def get_scoped_session():
    """ use Thread-local session """
    engine = DBEngine.instance()
    return engine.get_scoped_session()


def update_db(obj):
    session = get_scoped_session()
    try:
        session.merge( obj )
        session.commit()
    finally:
        session.close()


def main():
    engine = DBEngine.instance()
    engine.mapper('cust_instance', User)
    instance = User()
    print dir(instance)


if __name__=="__main__":
    main()

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值