SQLAlchemy

pip install sqlalchemy

基本操作

https://blog.csdn.net/shuaizy2017/article/details/80297837?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522159226910019724843315799%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=159226910019724843315799&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-1-80297837.pc_search_back_js&utm_term=python+sqlalchemy

参考文章2:

https://blog.csdn.net/liereli/article/details/80020033?ops_request_misc=&request_id=&biz_id=102&utm_term=python%20sqlalchemy&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-1-80020033

文章:

正确生成浮点型的方法,解决sqlachemy Float浮点型的坑,生成float类型时,长度和精度均为0,导致查询不到结果!

http://www.mamicode.com/info-detail-2488235.html

from sqlalchemy.dialects.mysql import FLOAT
float_5 = Column(FLOAT(precision=10, scale=2))

db_session.execute()写入操作同样需要执行

db_session.commit()

 

SQLAlchemy常用数据类型:
1. Integer:整形,映射到数据库中是int类型。
2. Float:浮点类型,映射到数据库中是float类型。他占据的32位。
3. Double:双精度浮点类型,映射到数据库中是double类型,占据64位。
4. String:可变字符类型,映射到数据库中是varchar类型.
5. Boolean:布尔类型,映射到数据库中的是tinyint类型。
6. DECIMAL:定点类型。是专门为了解决浮点类型精度丢失的问题的。在存储钱相关的字段的时候建议大家都使用这个数据类型。并且这个类型使用的时候需要传递两个参数,第一个参数是用来标记这个字段总能能存储多少个数字,第二个参数表示小数点后有多少位。
7. Enum:枚举类型。指定某个字段只能是枚举中指定的几个值,不能为其他值。在ORM模型中,使用Enum来作为枚举

8. Date:存储时间,只能存储年月日。映射到数据库中是date类型。在Python代码中,可以使用`datetime.date`来指定

9. DateTime:存储时间,可以存储年月日时分秒毫秒等。映射到数据库中也是datetime类型。在Python代码中,可以使用`datetime.datetime`来指定。示例代码如下:

10. Time:存储时间,可以存储时分秒。映射到数据库中也是time类型。在Python代码中,可以使用`datetime.time`来至此那个。

11. Text:存储长字符串。一般可以存储6W多个字符。如果超出了这个范围,可以使用LONGTEXT类型。映射到数据库中就是text类型。
12. LONGTEXT:长文本类型,映射到数据库中是longtext类型。

 

1 定义表结构

import sqlalchemy
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
 
engine = create_engine("mysql+pymysql://root:alex3714@localhost/testdb",
                                    encoding='utf-8', echo=True)
 
 
Base = declarative_base() #生成orm基类
 
class User(Base):
    __tablename__ = 'user' #表名
    id = Column(Integer, primary_key=True)
    name = Column(String(32))
    password = Column(String(64))
 
Base.metadata.create_all(engine) #创建表结构

2 创建和删除数据库表

#初始化数据库
def init_db():
    BaseModel.metadata.create_all(engine)

#删除数据库表
def drop_db():
    BaseModel.metadata.drop_all(engine)

3 增加数据

DBsession = sessionmaker(bind=engine)
#添加数据
def addUser():
    # 创建session对象,相当于MySQLdb里面的游标
    session = DBsession()
    # 创建新User对象:
    new_user1 = User(name='zhangsan', age=18)
    new_user2 = User(name='lisi', age=12)
    # 添加到session:
    session.add(new_user1)
    session.add(new_user2)
    # 提交即保存到数据库
    session.commit()
    # 关闭session
    session.close()

4 查询数据

查询全部数据

def queryAll():
    # 调用all()则返回所有行:
    session = DBsession()
    users = session.query(User).all()
    print([user for user in users])
    session.close()

查询部分数据

查询部分数据,使用filter和filter_by

5 更新数据

推荐用第一种方法,在不需要获取数据判断的情况下,可以只执行一次

#更新数据
def update_method1():
    session = DBsession()
    user = session.query(User).filter(User.id == '1')
    user.update({User.age: 10, User.name:'aaaa'})
    session.commit()
    # 关闭session
    session.close()

update_method1()


def update_method2():
    session = DBsession()
    user = session.query(User).filter_by(id='2').one()
    user.age = 10
    user.name='bbb'
    session.commit()
    # 关闭session
    session.close()

6 使用execute来执行查询

def execute():
    session = DBsession()
    user = session.execute("SELECT id,user_name as name,age FROM user WHERE id=:param",{"param":2}).fetchone()
    print(user)
    session.commit()
    # 关闭session
    session.close()

7 filter操作

equals:
query(Student).filter(Student.id == 10001)
not equals:
query(Student).filter(Student.id != 100)
LIKE:
query(Student).filter(Student.name.like(“%zy%”))

IN:
query(Student).filter(Student.name.in_(['zy', 'xiang', 'shang']))
not in
query(Student).filter(~Student.name.in_(['zy', 'xiang', 'shang']))
AND:
from sqlalchemy import and_
query(Student).filter(and_(Student.name == 'zy', Student.id ==10001))
或者
query(Student).filter(Student.name == 'edfadfj').filter(Student.address == 'beijing')

OR:
from sqlalchemy import or_
query.filter(or_(Student.name == 'fdedsfd', Student.age ==18))

8 删除

engine = create_engine('mysql://xiang:xiang@192.168.48.131/sqlalchemy')
DBSession = sessionmaker(bind=engine)
session = DBSession()
session.query(Student).filter(Student.id == 10001).delete()
session.commit()
session.close() 

9 one和first区别

one()    返回且仅返回一个查询结果。当结果的数量不足一个或者多于一个时会报错。
把上面的all改成one就报错了。
first()    返回至多一个结果,而且以单项形式,而不是只有一个元素的tuple形式返回这个结果.
my_stdent = session.query(Student).filter(Student.name.like("%ling%")).first()
print(my_stdent)
结果:
<__main__.Student object at 0x030A3610>
 

10 filter和filter_by区别

filter()和filter_by()的区别:
Filter:  可以像写 sql 的 where 条件那样写 > < 等条件,但引用列名时,需要通过 类名.属性名 的方式。 
filter_by:  可以使用 python 的正常参数传递方法传递条件,指定列名时,不需要额外指定类名。,参数名对应名类中的属性名,但似乎不能使用 > < 等条件。

当使用filter的时候条件之间是使用“==",fitler_by使用的是"="。
user1 = session.query(User).filter_by(id=1).first()
user1 = session.query(User).filter(User.id==1).first()

filter不支持组合查询,只能连续调用filter来变相实现。
而filter_by的参数是**kwargs,直接支持组合查询。
比如:
q = sess.query(IS).filter(IS.node == node and IS.password == password).all()
 

11 统计分组排序

统计、分组、排序
统计count()
print(session.query(Student).filter(Student.name.like("%in%")).count())
分组 group_by()
std_group_by = session.query(Student).group_by(Student.age)
print(std_group_by)
结果的sql语句如下:
SELECT student.id AS student_id, student.name AS student_name, student.age AS student_age, student.address AS student_address 
FROM student GROUP BY student.age

排序 order_by()     反序在order_by里面用desc()方法
std_ord_desc = session.query(Student).filter(Student.name.like("%ling%")).order_by(Student.id.desc()).all()
for i in std_ord_desc:
    print(i.id)

12 连接池

from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session
from models import Student,Course,Student2Course

engine = create_engine(
        "mysql+pymysql://root:123456@127.0.0.1:3306/s9day120?charset=utf8",
        max_overflow=0,  # 超过连接池大小外最多创建的连接
        pool_size=5,  # 连接池大小
        pool_timeout=30,  # 池中没有线程最多等待的时间,否则报错
        pool_recycle=-1  # 多久之后对线程池中的线程进行一次连接的回收(重置),默认2小时
    )
SessionFactory = sessionmaker(bind=engine)
session = scoped_session(SessionFactory)


def task():
    """"""
    # 方式一:
    """
    # 查询
    # cursor = session.execute('select * from users')
    # result = cursor.fetchall()

    # 添加
    cursor = session.execute('INSERT INTO users(name) VALUES(:value)', params={"value": 'wupeiqi'})
    session.commit()
    print(cursor.lastrowid)
    """
    # 方式二:
    """
    # conn = engine.raw_connection()
    # cursor = conn.cursor()
    # cursor.execute(
    #     "select * from t1"
    # )
    # result = cursor.fetchall()
    # cursor.close()
    # conn.close()
    """

    # 将连接交还给连接池
    session.remove()


from threading import Thread

for i in range(20):
    t = Thread(target=task)
    t.start()

————————————————
版权声明:本文为CSDN博主「shuaizy2017」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/shuaizy2017/article/details/80297837

13 flask中的使用

http://docs.jinkan.org/docs/flask/patterns/sqlalchemy.html

官方推荐了4种方法,第一种是用Flask-SQLAlchemy 扩展

第二种是显示调用,如下

SQLAlchemy 中的 declarative 扩展是最新的使用 SQLAlchemy 的方法。它允许您同时定义表和模型,就像 Django 一样工作。除了下文所介绍的内容外,我们建议您参考 declarative 扩展的官方文档。

这是一个 database.py 模块的例子:

from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base

engine = create_engine('sqlite:tmp/test.db', convert_unicode=True)
db_session = scoped_session(sessionmaker(autocommit=False,
                                         autoflush=False,
                                         bind=engine))
Base = declarative_base()
Base.query = db_session.query_property()

def init_db():
    # 在这里导入所有的可能与定义模型有关的模块,这样他们才会合适地
    # 在 metadata 中注册。否则,您将不得不在第一次执行 init_db() 时
    # 先导入他们。
    import yourapplication.models
    Base.metadata.create_all(bind=engine)

为了定义您的模型,仅仅构造一个上面代码编写的 Base 类的子类。如果您好奇为何我们在这里不用担心多线程的问题(就像我们在先前使用 g 对象操作 SQLite3 的例子一样):那是因为 SQLAlchemy 已经在 scoped_session 类当中为我们完成了这些任务。

在您的应用当中以一个显式调用 SQLAlchemy , 您只需要将如下代码放置在您应用的模块中。Flask 将会在请求结束时自动移除数据库会话:

from yourapplication.database import db_session

@app.teardown_request
def shutdown_session(exception=None):
    db_session.remove()

这是一个模型的例子(将代码放入 models.py 或类似文件中):

from sqlalchemy import Column, Integer, String
from yourapplication.database import Base

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    name = Column(String(50), unique=True)
    email = Column(String(120), unique=True)

    def __init__(self, name=None, email=None):
        self.name = name
        self.email = email

    def __repr__(self):
        return '<User %r>' % (self.name)

您可以使用 init_db 函数创建一个数据库:

>>> from yourapplication.database import init_db
>>> init_db()

按照如下方式将数据实体插入数据库:

>>> from yourapplication.database import db_session
>>> from yourapplication.models import User
>>> u = User('admin', 'admin@localhost')
>>> db_session.add(u)
>>> db_session.commit()

查询代码也很简单:

>>> User.query.all()
[<User u'admin'>]
>>> User.query.filter(User.name == 'admin').first()
<User u'admin'>

常用类型

常用的 SQLAlchemy 字段类型

类型名    python中类型    说明
Integer    int    普通整数,一般是32位
SmallInteger    int    取值范围小的整数,一般是16 位
BigInteger    int 或 long    不限制精度的整数
Float    float    浮点数
Numeric    decimal.Decimal    普通整数,一般是32位
String    str    变长字符串
Text    str    变长字符串,对较长或不限长度的字符串做了优化
Unicode    unicode    变长 Unicode 字符串
UnicodeText    unicode    变长Unicode字符串,对较长或不限长度的字符串做了优化
Boolean    bool    布尔值
Date    datetime.date    时间
Time    datetime.datetime    日期和时间
LargeBinary    str    二进制文件
————————————————
版权声明:本文为CSDN博主「furuiyang_」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/enjolras_fuu/article/details/82792411

默认值

import uuid

def gen_id():

   return uuid.uuid4().hex

id = db.Column(db.String(32), default=gen_id, primary_key=True)

Column常用参数

  • default:默认值
  • nullable:是否可有
  • primary_key:是否为主键
  • unique:是否唯一
  • autoincrement:是否自动增长
  • onupdate:更新的时候执行的函数
  • name:该属性在数据库中的字段映射

外链:

https://www.cnblogs.com/alex3714/articles/5978329.html

 

使用sql语句

sql = """\
       select  `id`, `name`, `mobile`
    from  `TUser`  limit 5 ;
       """
    print(f'sql:{sql}')
    try:
        resultproxy = session.execute(
            text(sql)
        )
    except Exception as e:
        print(e)
        results = []
    else:
        results = resultproxy.fetchall()

    print(results)

————————————————
版权声明:本文为CSDN博主「阿常呓语」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u010339879/article/details/84890642

 

 

 

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值