Flask-SQLAchemy

SQLALchemy, ORM框架(詳細點我html

做用: 幫助咱們使用類和對象快速實現數據庫操做。java

數據庫:
  - 原生:
    - MySQLdb
    -不支持python3
  - pymysql
    -支持python 3/2
  - ORM框架
    - SQLAlchemypython

建立表mysql

import datetime
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column,UniqueConstraint
from sqlalchemy import Integer,String,DateTime,ForeignKey
from sqlalchemy.orm import relationship
from engine import engine

Base = declarative_base()

#類名就至關於表名
class Userinfo(Base):
	__tablename__ = 'userinfo'

	id = Column(Integer, primary_key=True, autoincrement=True)
	name = Column(String(32),index=True,nullable=True)
	pwd = Column(Integer,nullable=True)
	dept_id = Column(Integer,ForeignKey('dept.id'))
	c_time = Column(DateTime,default=datetime.datetime.now())

	#在表裏面不生成字段,就是方便查詢和添加數據用
	dp = relationship('Dept', backref='us')

class Dept(Base):
	__tablename__ = 'dept'
	id = Column(Integer, primary_key=True, autoincrement=True)
	name = Column(String(32),index=True,nullable=True)


#建立多對多的關係的時候,SQLAlchemy沒有ManytoMany的字段,
# 就不能幫咱們自動的生成第三張表,而是要靠咱們本身去建立第三張表,來記錄關係

#學生和課程是多對多關係的

class Student(Base):
	__tablename__ = 'student'
	id = Column(Integer, primary_key=True, autoincrement=True)
	name = Column(String(32), index=True, nullable=True)

	cdp = relationship('Course',secondary='student2course',backref='sdp')


class Course(Base):
	__tablename__ = 'course'
	id = Column(Integer, primary_key=True, autoincrement=True)
	name = Column(String(32), index=True, nullable=True)


class Student2Course(Base):
	__tablename__ = 'student2course'

	id = Column(Integer, primary_key=True, autoincrement=True)
	student_id = Column(Integer,ForeignKey('student.id'))
	course_id = Column(Integer,ForeignKey('course.id'))

	__table_args__ = (
		#聯合惟一
		UniqueConstraint('student_id', 'course_id', name='sc_id'),
		#聯合
		# Index('ix_id_name', 'name', 'extra'),
	)


#根據類建立數據庫,須要數據庫的鏈接

def create_all():
	Base.metadata.create_all(engine)

def drop_all():
	Base.metadata.drop_all(engine)


if __name__== '__main__':
	# drop_all()
	create_all()

 

鏈接數據庫sql

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker,scoped_session
engine = create_engine(
		'mysql+pymysql://root:123456789@127.0.0.1:3306/sqlalchemydb?charset=utf8',
		max_overflow = 0,
		pool_size = 5,
		pool_timeout = 10,
		pool_recycle = -1,
	)

#也須要要數據的鏈接
SessionFactory = sessionmaker(bind=engine)
# scoped_session 是基於 threading.local();從鏈接池中取一個鏈接放入本身的線程的空間裏面
# 因此多個線程,併發的時候,也是爲每一個線程本身的空間內有本身的一條鏈接,這樣就不衝突了。
session = scoped_session(SessionFactory)


#按照session = SessionFactory() 這樣的形式的時候,在每一次線程來的時候,
# 都須要每次都從鏈接池中獲取鏈接
'''
def task():
	session = SessionFactory()
	session.query(Student).all()
	session.close()

from threading import Thread

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


'''
session = scoped_session(SessionFactory)

def task():
	session.query(Student).all()
	session.remove()    把本身線程空間內的鏈接刪除掉。也就是將鏈接返回給鏈接池。

from threading import Thread

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

'''

 

對錶的操做數據庫

from SQLAlchemy_Demo import Userinfo,Dept,Student,Student2Course,Course
from engine import session
from sqlalchemy.orm import sessionmaker
#操做用sqlalchemy生成的表

# ############# 執行ORM操做 #############
#查詢
#filter()裏面是一個表達式
#filter_by()裏面是關鍵字傳參數了
# ret = session.query(Userinfo).filter(Userinfo.id>2).all()
# ret = session.query(Userinfo).filter_by(id=2).first()
# print(ret)

#增長數據
#一個對象就表明着一行數據
# obj = Userinfo(name='alex',pwd=123,dept_id=1)
# session.add(obj)
#批量的添加數據
# session.add_all([
# 	Userinfo(name='db',pwd=123,dept_id=1),
# 	Userinfo(name='xiaodong',pwd=123,dept_id=1),
# ])
# session.commit()
# session.close()

#刪除 .delete()
# session.query(Userinfo).filter(Userinfo.id >3).delete()
# session.commit()
# session.close()

#修改 update({})
# session.query(Userinfo).filter(Userinfo.id ==1).update({"name":"阿輝"})
#synchronize_session=False就能夠字符串的拼接了;默認的是數字的拼接。; Userinfo.name能夠用表裏面的數據
# session.query(Userinfo).filter(Userinfo.id ==1).update({Userinfo.name:Userinfo.name+'帥逼'},synchronize_session=False)
# session.query(Userinfo).filter(Userinfo.id ==1).update({Userinfo.pwd:Userinfo.pwd+999})
# session.commit()
# session.close()


#經常使用的操做
# 分組  後面跟條件 having

# from sqlalchemy.sql import func
# ret = session.query(Userinfo).group_by(Userinfo.extra).all()
#上面這查不了,由於分組後每組後多個,不知道給你返回哪個,須要你本身來指定。
# ret = session.query(
# func.max(Userinfo.id),
# ).group_by(Userinfo.dept_id).having(func.max(Userinfo.id) >2).all()
# print(ret)


#FK 連表操做   query要查詢哪張表裏面的什麼數據
# on 條件      Userinfo.dept_id == Dept.id       #join -- inner join
# user_data = session.query(Userinfo.id,Userinfo.name.label('username'),Dept.name).join(Dept,Userinfo.dept_id == Dept.id).all()

# isouter=True  -- > LEFT OUTER JOIN --  LEFT JOIN
# user_data = session.query(Userinfo.id,Userinfo.name.label('username'),Dept.name).join(Dept,Userinfo.dept_id == Dept.id,isouter=True).all()
# for item in user_data:
# 	print(item.id,item.username,item.name)

# print(session.query(Userinfo.id,Userinfo.name.label('username'),Dept.name).join(Dept,Userinfo.dept_id == Dept.id,isouter=True))

# ret = session.query(Dept).filter(Dept.name == '銷售').first()
# print(ret)

#FK關係表
#建立一個名稱爲: IT部門,再在該部門中添加一個員工:小光
#第一種方式:
	# dept_obj = Dept(name='IT部門')
	# session.add(dept_obj)
	# session.commit()
	#只要commit後 dept_obj這個建立的對象就是當前添加到表裏面的對象
	# dept_id = dept_obj.id
	# print(dept_id)
	# user_obj = Userinfo(name='小光',dept_id=dept_id,pwd=123)
	# session.add(user_obj)
	# session.commit()
	# session.close()
#第二種經過relation字段
# user_obj = Userinfo(name='小光',pwd=123,dp=Dept(name='IT部門'))
#
# session.add_all(user_obj)
# session.commit()

#建立一個名稱爲: IT部門,再在該部門中添加一個員工:小2,小3,小4
#以上的這種簡單的方法就不可取了。
#user_obj = Userinfo(name='小光',pwd=123,dp=Dept(name='IT部門'))
# user_objs = Userinfo(name='小光02',pwd=123,dp=Dept(name='IT部門'))
#這樣就生成了兩個IT部門,分別在對應的添加人。
#這樣要經過反向生成了
# obj=Dept(name='IT部門01')
# obj.us = [Userinfo(name='小2',pwd=123),Userinfo(name='小3',pwd=123)]
#
# session.add(obj)
#
# session.commit()
# session.close()

#ManytoMany  多對多關係表

#添加上python課程的小輝和小黑,上Linux的小黑,以及上go的小龍到數據庫中
#方式一,本身添加到三張表中
# session.add_all([Student(name='小輝'),Student(name='小黑'),Student(name='小龍')])

# session.add_all([Course(name='Python'),Course(name='Linux'),Course(name='go')])
# session.add_all([Student2Course(student_id=6,course_id=6),Student2Course(student_id=7,course_id=6),Student2Course(student_id=7,course_id=7),Student2Course(student_id=8,course_id=8)])
# session.commit()
# session.close()


#方式二:
# 建立一個新的課程,建立2個學生,而且爲兩個學生選取新建立的課程

# c_obj = Course(name='java')
# c_obj.sdp =[Student(name='01'),Student(name='02')]
#
# session.add(c_obj)
#幫咱們在三張表中建立數據
# session.commit()
# session.close()


#正常查詢的話,須要本身不斷的連表
#查詢上python課程的全部學生的姓名
# p_obj = session.query(Student2Course.student_id,Course.name,Student.name).join(Course,Student2Course.course_id ==Course.id).join(Student,Student2Course.student_id == Student.id).filter(Course.name=='python').all()
# print(p_obj)


# 上面的查詢須要本身連表,比較麻煩 所以用relationship字段來查詢,跟FK的類似。

c_obj = session.query(Course).filter(Course.name=='python').first()
ret = c_obj.sdp
for item in ret:
	print(item.name)

  

總結:flask

在flask中使用 flask-sqlalchemy的步驟:
		1.先在__init__.py文件中導入並實例化SQLAlchemy
			from flask_sqlalchemy import SQLAlchemy
			db = SQLAlchemy()    實例化的db裏面 什麼的有(SQLAlchemy相關的操做), 可是就是沒有數據庫的鏈接,所以必需要初始化 
			注意:
				-在外面實例化 -- db = SQLAlchemy() 
				-必須在導入藍圖以前 (由於要導入db,從而操做數據庫的)
				-必須導入models.py(這樣才能自動的幫咱們去找到對應的類,去生成對應的表)

		2. 初始化 (對取app裏面的配置文件,讀取數據庫的鏈接)
			db.init_app(app)

		3.在配置文件中寫入數據庫鏈接的配置
			SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:123456789@127.0.0.1:3306/sqlalchemydb?charset=utf8'
			SQLALCHEMY_POOL_SIZE = 10
			SQLALCHEMY_MAX_OVERFLOW = 2

		4.建立models.py中的類(對應數據庫的表)
			在與__init__同級目錄下建立models.py
			注意:此時的類必需要繼承db.Model
			class Userinfo(db.Model):
				__tablename__ = 'userinfo'

				id = Column(Integer, primary_key=True, autoincrement=True)
				name = Column(String(32),index=True,nullable=True)
				pwd = Column(Integer,nullable=True)
				dept_id = Column(Integer,ForeignKey('dept.id'))
				c_time = Column(DateTime,default=datetime.datetime.now())
		5.而後再最外面建立一個獨立的腳本,用來生成表。
			注意:要使用app上下文,拿到裏面的app
			#要應用到app上文管理
			from crm import db,create_app

			app = create_app()
			app_ctx = app.app_context()

			with app_ctx:
				# with 對象 的時候就會自動的觸發類的__enter__ 方法,而後執行下面的代碼,最後執行__exit__

				#__enter__是將app_ctx經過;LocalStack放入Local中,

				db.create_all()  #會調用LocalStack 從Local中獲取app,而後再從app中獲取配置。

				#__exit__ 是將當前的app_ctx對象從Local中移除掉

		6.基於ORM對數據庫進行操做。
			要導入db
			db.session 就至關於 之前使用的session了
			db.session.add(...)	
			#SQLAlchemy的應用:
			# from crm import db
			# from crm import models
			# userobj = models.Userinfo(name='小輝', pwd=123, dept_id=12)
			# userobj.dp = models.Dept(name='銷售')
			# db.session.add(userobj)
			# db.session.commit()
			# db.session.remove()
				
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息