python mysql单元测试示范卷_不写一句mysql操作数据库才是Python的风格!!3个ORM模型库示范...

用Python可以不用记住任何一句mysql,通过Python使用的ORM模型,简单来说就是一个库是一个对象,这个库里面的字段是这个对象的属性。

ORM解释:对象关系映射(英语:(Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换 。从效果上说,它其实是创建了一个可在编程语言里使用的--“虚拟对象数据库”。简单来说就是:一个库是一个对象,这个库里面的字段是这个对象的属性。

所有mysql语句封装在了这个对象的方法之中,直接使用相关方法。

介绍三款ORM模型:Peewee、Sqlalchemy、mongoengine以及其中遇到过的莫名问题

其中Peewee、Sqlalchemy是操作mysql和sqlite的,mongoengine是操作mongodb的,这三个库均可在Python3环境下使用

示例简介使用ORM模型实现数据库的增删改查,以及根据ORM模型映射创建数据库

1.Peewee

from peewee import *

from playhouse.db_url import connect

from playhouse.pool import PooledMySQLDatabase, PooledDatabase

from playhouse.shortcuts import model_to_dict, dict_to_model

import datetime

"""peewee提供了一个数据库的封装模型,playhouse.db_url为其连接的一种方式通过数据库的指定格式url连接

连接后创建完以后需要模型生成表使用db.connect(),db.create_tables([Person, Pet])"""

blog = PooledMySQLDatabase(

'peewee_test',

max_connections=8,

stale_timeout=300,

user='admin',

host='118.24.52.111',

password='123456!@#,.',

port=3306)

""""

http://docs.peewee-orm.com/en/latest/peewee/playhouse.html#PooledDatabase.manual_close

"""

# MYSQL_URL = \

# 'mysql://admin:6666666!@111.1111.111.111:3306/peewee_test?charset=utf8'

# blog = connect(MYSQL_URL) # 连接方式一

# 连接方式二

# blog = MySQLDatabase('test', user='root', host='localhost', port=3306)

class BaseModel(Model):

"""基类"""

class Meta:

database = blog

class Test(BaseModel):

"""参数解释 CharField:字符串类型 IntegerField:整型 DateTimeField:时间类型 ForeignKeyField:外键关联 unique:是否唯一 max_lenth:最大长度 verbose_name:表头名 null:是都为空 default:默认值"""

name = CharField(unique=True, max_length=50, verbose_name='用户名', null=False, default='你哈')

number = IntegerField(default=0, verbose_name='数字')

update_date = DateTimeField(verbose_name='更新时间', default=datetime.datetime.now)

def close(self):

blog.close()

class Tests(BaseModel):

title = CharField(verbose_name='标题', max_length=64)

site = CharField(verbose_name='前缀', max_length=32, unique=True)

article_type = ForeignKeyField(Test)

def create_tables():

"""生成数据表,在数据库中生成模型映射的表"""

blog.connect()

blog.create_tables([Tests, Test])

blog.close()

def drop_tables():

"""删除数据表"""

blog.connect()

blog.drop_tables([Tests, Test])

blog.close()

def insert(value):

"""插入数据,或者将属性作为参数传入Test(name='name',number=2222)"""

obj = Test()

obj.name = value

obj.number = 99

obj.save()

def updata():

""""更新数据"""

obj = Test.get(Test.name == '更新')

obj.name = '更新完毕'

obj.number = 100

obj.save()

def select_all():

"""查询所有数据"""

ret = Test.select()

for obj in ret:

print(obj.name)

def select_test():

"""查询条件数据"""

Test.select().where((Test.name.contains('测试'))) .count() # 包含指定内容返回集合

Test.select().where((Test.name == '测试') | (Test.number == 9999)).first() # 条件或

Test.select().where((Test.name == '测试'), (Test.number == 9999)).first() # 条件并

Test.select().join(Tests).where(Tests.title == 'title').execute() # 关联查询

obj = Test.get(Test.name == 'yang')

if obj:

print(obj.name)

else:

print('none have')

def delete_a(i):

"""删除数据"""

obj = Test.get(Test.id == i)

obj.delete_instance()

def sort():

"""对返回结果列排序"""

set = Test.select().order_by(Test.name)

def to_dict():

"""把模型数据转为字典对象"""

user = Test.create(username='jack')

u = model_to_dict(user)

return u

def to_model():

"""生成model对象"""

user_data = {'id': 2, 'username': 'charlie'}

user = dict_to_model(Test, user_data)

def close():

db.close()

2.Sqlalchemy

from sqlalchemy import Column, create_engine

from sqlalchemy.ext.declarative import declarative_base

from sqlalchemy.orm import sessionmaker

from sqlalchemy.types import CHAR, Integer, String, SMALLINT

"""

__tablename__:指定表名Column:行声明,可指定主键Integer:int类型String:字符串Float:浮点Boolean:布尔DateTime:日期和时间Text:文本LongText:长文本

父类BaseModel会调用所有继承他的子类来生成表结构primary_key:True/False 是否为主键unique:是否唯一nullable:是否为空default:默认值"""

MYSQL_SETTING = "mysql://lkj:123456lkj@localhost:3306/blog?charset=utf8"

engine = create_engine(

MYSQL_SETTING, pool_size=20, max_overflow=0, pool_recycle=3600)

DBSession = sessionmaker(bind=engine) # 创建DBSession类型:类似数据库连接

BaseModel = declarative_base()

class Test(BaseModel):

__tablename__ = 'test_table'

id = Column(Integer, primary_key=True)

url = Column(String(128)) # 字符串类型

update_time = Column(DateTime, default=datetime.datetime.now())

def to_dict(self): # 将读取的数据和转化成字典

return {c.name: getattr(self, c.name, None) for c in self.__table__.columns}

def init_db():

"""生成数据表"""

BaseModel.metadata.create_all(engine)

def drop_db():

"""删除数据表"""

BaseModel.metadata.drop_all(engine)

if __name__ == '__main__':

init_db()

"""添加数据"""

session = DBSession()

new_data = Test(url='', update_time='')

session.add(new_data) # 添加

session.commit() # 提交

"""查询数据"""

session = DBSession()

num = session.query(Test).filter(

Test.url == 'url', Test.id == '22').count() # 查询多条件

session.commit()

session.close()

"""删除数据"""

session = DBSession()

test = session.query(Test).filter(Test.url == "user1").first()

session.delete(test)

session.commit()

session.close()

"""更新数据"""

session = DBSession()

test = session.query(Test).filter(Test.url == "user1").first()

test.url = 'www.test.com'

session.commit()

session.close()

3.mongoengine

from mongoengine import connect, Document, EmbeddedDocument, DynamicDocument, \

StringField, IntField, FloatField, ListField, EmbeddedDocumentField, DictField

import datetime

connect(db='test',

host="mongodb://admin:6666666@111.111.111.111:27017/?authSource=admin")

if __name__ == '__main__':

"""

简单使用说明-及其使用案例

Document #定义基本模式继承该类——适用于储存字典结构变化不定的数据 EmbeddedDocument #申明内嵌文档 EmbeddedDocumentField #嵌入文档的方法 DynamicDocument # 动态添加字段方法--适用于储存固定格式字典并要求验证的

StringFiled(regex=None,max_length=None,min_lenght=None) #字符串类型

IntField(min_value=None,max_value=None) #整数类型

FloatField(min_value=None,max_value=None) #字符串类型

BooleanField() #布尔类型

DateTimeField() #时间类型

listField() #可以插入列表的

DictField() #字典类型

ReferenceField() #参照类型

SequenceField() #自动产生一个数列、 递增的

通用参数 default #默认值 也可以是一个函数 可调用类型

required #是否必须赋值 true false

primary_key #插入数据是否重复

null #赋值是否可以为空

choices #列表的范围

unique #当前列只能是唯一的 """

SEX_CHICES = (

('male', '男'),

('female', '女')

)

class Grade(EmbeddedDocument):

"""成绩"""

name = StringField(required=True)

score = FloatField(required=True)

class Student(DynamicDocument):

"""学生"""

name = StringField(max_length=32, required=True)

age = IntField(required=True)

sex = StringField(choices=SEX_CHICES, required=True)

grade = FloatField()

address = StringField()

grades = ListField(EmbeddedDocumentField(Grade))

meta = {

'collection': 'students',

# 排序功能,按照分数倒序

'ordering': ['-grade']

}

class TestMongoEngine(object):

def add_one(self):

"""添加一条数据到数据库"""

yuwen = Grade(

name='语文',

score=90)

shuxue = Grade(

name='数学',

score=100)

stu_obj = Student(

name='张三丰',

age=15,

grades=[yuwen, shuxue],

sex='male'

)

# 直接添加remark字段是无法添加成功的,需要引入动态添加字段的方法DynamicDocument

stu_obj.remark = 'remark'

stu_obj.save()

return stu_obj

def get_one(self):

""" 获取单条数据 """

return Student.objects.first()

def get_more(self):

""" 获取多条数据 """

# return Student.objects

return Student.objects.all()

def get_one_from_oid(self, oid):

""" 查询指定id的数据 """

return Student.objects.filter(id=oid).first()

def update(self):

""" 修改数据 """

# 修改一条数据

# res = Student.objects.filter(sex='male').update_one(inc__age=1)

# return res

# 修改多条数据

res = Student.objects.filter(sex='male').update(inc__age=10)

return res

def delete(self):

""" 删除数据 """

# 删除一条数据

# res = Student.objects.filter(sex='male').first().delete()

# return res

# 删除多条数据

res = Student.objects.filter(gender='male').delete()

test = TestMongoEngine()

test.add_one()

注意:peewee和sqlalchemy如果使用的是单个连接在多进程使用中会锁表,上面案列连接方式都是连接池的方式,可以避免在多进程中锁表。

------------------------------

ID:Python之战

|作|者|公(zhong)号:python之战

专注Python,专注于网络爬虫、RPA的学习-践行-总结

喜欢研究和分享技术瓶颈,欢迎关注

独学而无友,则孤陋而寡闻!

---------------------------

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值