一。自定义命令。

  在flask中也可以将应用改写成可以使用命令的形式,需要用到模块:

  1. pip install flask-script

  使用关键字manage使得其能使用终端启动:

  1. from flask import Flask
  2. from flask_script import Manager
  3. app = Flask(__name__)
  4. manager=Manager(app)
  5.  
  6. @app.route("/")
  7. def index():
  8. return "ok"

  在启动的时候就可以使用以下命令:

  1. python 文件名.py runserver

  使用命令运行函数:

  1. @manager.command
  2. def custom(arg,a):
  3. print(arg,a)

  运行命令:

  1. python t1.py custom 1 2

  当然,可以自定义命令:

  1. @manager.option('-n','--name',dest='name')
  2. @manager.option('-u','--url',dest='url')
  3. def cmd(name,url):
  4. print(name,url)

  函数中,每有一个参数,就需要有一个option,第一个参数是别名,第二个参数是详细名,两者都可以用做运行,dest代表绑定的关键字参数。

  运行命令

  1. python t1.py cmd -n lzx -u 111
  2.  
  3. python t1.py cmd --name lzx --url 111

二。多app应用

  需要导入模块:

  1. from werkzeug.wsgi import DispatcherMiddleware
  2. from werkzeug.serving import run_simple
  3. from flask import Flask
  4. app1 = Flask('app01')
  5. app2 = Flask('app02')

  当这个模块使用时:

  1. @app1.route('/index')
  2. def index():
  3. return "app01"
  4.  
  5. @app2.route('/index')
  6. def index2():
  7. return "app2"
  8. dm = DispatcherMiddleware(app1, {
  9. '/sec12': app2,
  10. })
  11. if __name__ == "__main__":
  12.  
  13. run_simple('localhost', 5000, dm)

  执行方法时run,当页面访问时,需要将dm中的前缀加上才能访问。

三。wtform

  导入模块

  1. pip install wtforms

  使用

  1. from flask import Flask, render_template, request, redirect
  2. from wtforms import Form
  3. from wtforms.fields import simple
  4. from wtforms import validators
  5. from wtforms import widgets
  6.  
  7. app = Flask(__name__)
  8.  
  9. app.debug = True
  10.  
  11. class LoginForm(Form):
  12. # 字段(内部包含正则表达式)
  13. name = simple.StringField(
  14. label='用户名',
  15. validators=[
  16. validators.DataRequired(message='用户名不能为空.'),
  17. validators.Length(min=2, max=6, message='用户名长度必须大于%(min)d且小于%(max)d')
  18. ],
  19. widget=widgets.TextInput(), # 页面上显示的插件
  20. render_kw={'class': 'form-control'}
  21. )
  22. # 字段(内部包含正则表达式)
  23. pwd = simple.PasswordField(
  24. label='密码',
  25. validators=[
  26. validators.DataRequired(message='密码不能为空.'),
  27. validators.Length(min=8, message='密码长度必须大于%(min)d'),
  28. # validators.Regexp(regex="^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[$@$!%*?&])[A-Za-z\d$@$!%*?&]{8,}",
  29. # message='密码至少8个字符,至少1个大写字母,1个小写字母,1个数字和1个特殊字符')
  30.  
  31. ],
  32. widget=widgets.PasswordInput(),
  33. render_kw={'class': 'form-control'}
  34. )
  35.  
  36. @app.route('/login', methods=['GET', 'POST'])
  37. def login():
  38. if request.method == 'GET':
  39. form = LoginForm()
  40. return render_template('login.html', form=form)
  41. else:
  42. form = LoginForm(formdata=request.form)
  43. if form.validate():
  44. print('用户提交数据通过格式验证,提交的值为:', form.data)
  45. else:
  46. print(form.errors)
  47. return render_template('login.html', form=form)
  48.  
  49. if __name__ == '__main__':
  50. app.run()

  label代表的是字段前缀,vaildate代表的是校验,widget,代表的是input类型,render_kw,代表的是定义的类或元素。

  template

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. <h1>登录</h1>
  9. <form method="post">
  10. <p>{{form.name.label}} {{form.name}} {{form.name.errors[0] }}</p>
  11. <p>{{form.pwd.label}} {{form.pwd}} {{form.pwd.errors[0] }}</p>
  12. <input type="submit" value="提交">
  13. </form>
  14. </body>
  15. </html>

  所有的form类型:

  1. from flask import Flask, render_template, request, redirect
  2. from wtforms import Form
  3. from wtforms.fields import core
  4. from wtforms.fields import html5
  5. from wtforms.fields import simple
  6. from wtforms import validators
  7. from wtforms import widgets
  8.  
  9. app = Flask(__name__, template_folder='templates')
  10. app.debug = True
  11.  
  12. class RegisterForm(Form):
  13. def validate_pwd_confirm(self, field):
        # 钩子函数
  14. """
  15. 自定义pwd_confirm字段规则,例:与pwd字段是否一致
  16. :param field:
  17. :return:
  18. """
  19. # 最开始初始化时,self.data中已经有所有的值
  20. print(field.data)
  21. if field.data !="sb":
  22. #raise validators.ValidationError("sb") # 继续后续验证
  23. raise validators.StopValidation("SB") # 不再继续后续验证
  24.  
  25. # if field.data != self.data['pwd']:
  26. # raise validators.ValidationError("密码不一致") # 继续后续验证
  27. #raise validators.StopValidation("密码不一致") # 不再继续后续验证
  28.  
  29. name = simple.StringField(
  30. label='用户名',
  31. validators=[
  32. validators.DataRequired()
  33. ],
  34. widget=widgets.TextInput(),
  35. render_kw={'class': 'form-control'},
  36. default='tank'
  37. )
  38.  
  39. pwd = simple.PasswordField(
  40. label='密码',
  41. validators=[
  42. validators.DataRequired(message='密码不能为空.')
  43. ],
  44. widget=widgets.PasswordInput(),
  45. render_kw={'class': 'form-control'}
  46. )
  47.  
  48. pwd_confirm = simple.PasswordField(
  49. label='重复密码',
  50. validators=[
  51. validate_pwd_confirm,
  52. validators.DataRequired(message='重复密码不能为空.'),
  53. #validators.EqualTo('pwd', message="两次密码输入不一致")
  54. ],# 判断重复密码
  55. widget=widgets.PasswordInput(),
  56. render_kw={'class': 'form-control'}
  57. )
  58.  
  59. email = html5.EmailField(
  60. label='邮箱',
  61. validators=[
  62. validators.DataRequired(message='邮箱不能为空.'),
  63. validators.Email(message='邮箱格式错误')
  64. ],
  65. widget=widgets.TextInput(input_type='email'),
  66. render_kw={'class': 'form-control'}
  67. )
  68.  
  69. gender = core.RadioField(
  70. label='性别',
  71. choices=(
  72. (1, '男'),
  73. (2, '女'),
  74. ),
  75. coerce=int # “1” “2” # 将选择的数据类型变为数字类型
  76. )
  77. city = core.SelectField(
  78. label='城市',
  79. choices=(
  80. ('bj', '北京'),
  81. ('sh', '上海'),
  82. )
  83. )
  84.  
  85. hobby = core.SelectMultipleField(
  86. label='爱好',
  87. choices=(
  88. (1, '篮球'),
  89. (2, '足球'),
  90. ),
  91. coerce=int
  92. )
  93.  
  94. favor = core.SelectMultipleField(
  95. label='喜好',
  96. choices=(
  97. (1, '篮球'),
  98. (2, '足球'),
  99. ),
  100. widget=widgets.ListWidget(prefix_label=False),
  101. option_widget=widgets.CheckboxInput(),
  102. coerce=int,
  103. default=[1, 2]
  104. )
  105.  
  106. def __init__(self, *args, **kwargs):
  107. super(RegisterForm, self).__init__(*args, **kwargs)
  108. self.favor.choices = ((1, '篮球'), (2, '足球'), (3, '羽毛球'))
  109. self.favor.data=[1,] # 设置默认值
          # 可以修改字段中的元素
  110.  
  111. @app.route('/register', methods=['GET', 'POST'])
  112. def register():
  113. if request.method == 'GET':
  114. form = RegisterForm(data={'gender': 2,'hobby':[1,]}) # initial
          # 设置默认值
  115. return render_template('register.html', form=form)
  116. else:
  117. form = RegisterForm(formdata=request.form)
  118. if form.validate():
  119. print('用户提交数据通过格式验证,提交的值为:', form.data)
  120. else:
  121. print(form.errors)
  122. return render_template('register.html', form=form)
  123.  
  124. if __name__ == '__main__':
  125. app.run()

四。SQLAlchemy

  这是一个基于python的orm框架,可以实现sql语句的操作。其也是由pymysql等数据中间键来操作的。

  安装:

  1. pip3 install sqlalchemy

  (不常用)使用原生sql语句操作数据库。

  1. import time
  2. import threading
  3. import sqlalchemy
  4. from sqlalchemy import create_engine
  5. from sqlalchemy.engine.base import Engine
  6.  
  7. engine = create_engine(
  8. "mysql+pymysql://root:123456@127.0.0.1:3306/test?charset=utf8",
  9. max_overflow=0, # 超过连接池大小外最多创建的连接
  10. pool_size=5, # 连接池大小
  11. pool_timeout=30, # 池中没有线程最多等待的时间,否则报错
  12. pool_recycle=-1 # 多久之后对线程池中的线程进行一次连接的回收(重置)
  13. )
  14. def task(arg):
  15. conn = engine.raw_connection()
  16. cursor = conn.cursor()
  17. cursor.execute(
  18. "select * from app01_book"
  19. )
  20. result = cursor.fetchall()
  21. print(result)
  22. cursor.close()
  23. conn.close()
  24.  
  25. for i in range(20):
  26. t = threading.Thread(target=task, args=(i,))
  27. t.start()

  orm使用

  orm需要导入各种数据进行配置

  1. import datetime
  2. from sqlalchemy import create_engine
  3. from sqlalchemy.ext.declarative import declarative_base
  4. from sqlalchemy import Column, Integer, String, Text, ForeignKey, DateTime, UniqueConstraint, Index
  5. Base = declarative_base()
  6.  
  7. class Users(Base):
  8. __tablename__ = 'users' # 数据库表名称
  9. id = Column(Integer, primary_key=True) # id 主键
  10. name = Column(String(32), index=True, nullable=False) # name列,索引,不可为空
  11. # email = Column(String(32), unique=True)
  12. #datetime.datetime.now不能加括号,加了括号,以后永远是当前时间
  13. # ctime = Column(DateTime, default=datetime.datetime.now)
  14. # extra = Column(Text, nullable=True)
  15.  
  16. __table_args__ = (
  17. # UniqueConstraint('id', 'name', name='uix_id_name'), #联合唯一
  18. # Index('ix_id_name', 'name', 'email'), #索引
  19. )
  20.  
  21. def init_db():
  22. """
  23. 根据类创建数据库表
  24. :return:
  25. """
  26. engine = create_engine(
  27. "mysql+pymysql://root:123456@127.0.0.1:3306/aaa?charset=utf8",
  28. max_overflow=0, # 超过连接池大小外最多创建的连接
  29. pool_size=5, # 连接池大小
  30. pool_timeout=30, # 池中没有线程最多等待的时间,否则报错
  31. pool_recycle=-1 # 多久之后对线程池中的线程进行一次连接的回收(重置)
  32. )
  33.  
  34. Base.metadata.create_all(engine)
  35.  
  36. def drop_db():
  37. """
  38. 根据类删除数据库表
  39. :return:
  40. """
  41. engine = create_engine(
  42. "mysql+pymysql://root:123456@127.0.0.1:3306/aaa?charset=utf8",
  43. max_overflow=0, # 超过连接池大小外最多创建的连接
  44. pool_size=5, # 连接池大小
  45. pool_timeout=30, # 池中没有线程最多等待的时间,否则报错
  46. pool_recycle=-1 # 多久之后对线程池中的线程进行一次连接的回收(重置)
  47. )
  48.  
  49. Base.metadata.drop_all(engine)
  50.  
  51. if __name__ == '__main__':
  52. # drop_db()
  53. init_db()

  所有的类表需要继承自base,否则不在管理之内。增删表都只能管理他的子类。不能增加字段,也不能删除字段,但是可以将数据库字段和orm字段设置成一样的,也可以用。

  3.app导入:

  1. from sqlalchemy.orm import sessionmaker
  2. from sqlalchemy import create_engine
  3. from models import Users
  4. #"mysql+pymysql://root@127.0.0.1:3306/aaa"
  5. engine = create_engine("mysql+pymysql://root:123456@127.0.0.1:3306/aaa", max_overflow=0, pool_size=5)
  6. Connection = sessionmaker(bind=engine)
  7.  
  8. # 每次执行数据库操作时,都需要创建一个Connection
  9. con = Connection()
  10.  
  11. # ############# 执行ORM操作 #############
  12. obj1 = Users(name="lqz")
  13. con.add(obj1)
  14. # 提交事务
  15. con.commit()
  16.  
  17. # 关闭session,其实是将连接放回连接池
  18. con.close()

五。scoped_session

  scoped_session可以使得线程安全,保证所有线程之间不会互相操作。

  1. from sqlalchemy.orm import sessionmaker
  2. from sqlalchemy import create_engine
  3. from sqlalchemy.orm import scoped_session
  4. from models import Users
  5.  
  6. engine = create_engine("mysql+pymysql://root:123@127.0.0.1:3306/flask", max_overflow=0, pool_size=5)
  7. Session = sessionmaker(bind=engine)
  8.  
  9. """
  10. # 线程安全,基于本地线程实现每个线程用同一个session
  11. # 特殊的:scoped_session中有原来方法的Session中的一下方法:
  12.  
  13. public_methods = (
  14. '__contains__', '__iter__', 'add', 'add_all', 'begin', 'begin_nested',
  15. 'close', 'commit', 'connection', 'delete', 'execute', 'expire',
  16. 'expire_all', 'expunge', 'expunge_all', 'flush', 'get_bind',
  17. 'is_modified', 'bulk_save_objects', 'bulk_insert_mappings',
  18. 'bulk_update_mappings',
  19. 'merge', 'query', 'refresh', 'rollback',
  20. 'scalar'
  21. )
  22. """
  23. #scoped_session类并没有继承Session,但是却又它的所有方法
  24. session = scoped_session(Session)
  25. # ############# 执行ORM操作 #############
  26. obj1 = Users(name="jason")
  27. session.add(obj1)
  28.  
  29. # 提交事务
  30. session.commit()
  31. # 关闭session
  32. session.close()

六,基本增删改操作:

  使用方法session.add可以添加表对象添加数据。

  使用add_all可以添加列表套对象的方式添加数据。

  删除使用session.query(User).filter(User.id>2).delete()

  首先查出改字段对象,执行delete方法删除那些对象。

  修改表数据‘

  1。session.query(User).filter(User.id>2).updata({'age':30}),字典代表的是字段和数据。

  2.session.query(Users).filter(Users.id == 3).update({Users.name: Users.name + "sb"}, synchronize_session=False)

  类似于f查询,将其字段进行拼接,但是synchronize_session必须设置成false。(仅对于字符串)

  3.session.query(Users).filter(Users.id == 7).update({"age": Users.age + 16}, synchronize_session="evaluate")

  如果操作的数据,需要设置synchronize_session="evaluate"

  如果session.query(Users)不加all,则打印的就是原生sql语句

  1. import time
  2. import threading
  3.  
  4. from sqlalchemy.ext.declarative import declarative_base
  5. from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index
  6. from sqlalchemy.orm import sessionmaker, relationship
  7. from sqlalchemy import create_engine
  8. from sqlalchemy.sql import text
  9.  
  10. from models import Users
  11. engine = create_engine("mysql+pymysql://root:123@127.0.0.1:3306/flask", max_overflow=0, pool_size=5)
  12. Session = sessionmaker(bind=engine)
  13.  
  14. session = Session()
  15.  
  16. # ################ 添加 ################
  17.  
  18. # obj1 = Users(name="wupeiqi",age=40)
  19. # session.add(obj1)
  20. #
  21. # session.add_all([
  22. # Users(name="tank"),
  23. # Users(name="jason"),
  24. # #Hosts(name="c1.com"),
  25. # ])
  26. # session.commit()
  27.  
  28. # ################ 删除 ################
  29.  
  30. # session.query(Users).filter(Users.id == 5).delete()
  31. # session.commit()
  32.  
  33. # ################ 修改 ################
  34.  
  35. #传字典
  36. #session.query(Users).filter(Users.id ==4 ).update({"age" : 30,})
  37. #类似于django的F查询
  38. #session.query(Users).filter(Users.id == 3).update({Users.name: Users.name + "sb"}, synchronize_session=False)
  39. #session.query(Users).filter(Users.id == 7).update({"age": Users.age + 16}, synchronize_session="evaluate")
  40. # session.commit()
  41.  
  42. # ################ 查询 ################
  43.  
  44. # r1 = session.query(Users).all()
  45. # print(r1),query后面可以增加多个表
  46. #只取age列,把name重命名为xx,label代表的是起别名
  47. # r2 = session.query(Users.name.label('sb'), Users.age).filter(Users.id==8).first()
  48. # print(r2.sb)
  49. #filter传的是表达式,filter_by传的是参数
  50. # r3 = session.query(Users).filter(Users.name == "jason").all()
  51. # print(r3)
  52. # r4 = session.query(Users).filter_by(name='jason').all()
  53. # print(r4)
  54. # r5 = session.query(Users).filter_by(name='lqz').first(),.first取出其中的第一条。
  55. #:value 和:name 相当于占位符,用params传参数
  56. #r6 = session.query(Users).filter(text("id<:value and name=:name")).params(value=224, name='fred').order_by(Users.id).all()
  57. #自定义查询sql
  58. #r7 = session.query(Users).from_statement(text("SELECT * FROM users where name=:name")).params(name='ed').all()
  59.  
  60. #增,删,改都要commit()
  61. session.close()

  如果需要对其打印输出的字段可以设置:

  1. def __repr__(self):
  2. return self.name

七。查询

  1. import time
  2. import threading
  3. from sqlalchemy.ext.declarative import declarative_base
  4. from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index
  5. from sqlalchemy.orm import sessionmaker, relationship
  6. from sqlalchemy import create_engine
  7. from sqlalchemy.sql import text
  8.  
  9. from models import Users
  10. engine = create_engine("mysql+pymysql://root:123@127.0.0.1:3306/flask", max_overflow=0, pool_size=5)
  11. Session = sessionmaker(bind=engine)
  12.  
  13. session = Session()
  14. # 条件
  15. # ret = session.query(Users).filter_by(name='lqz').all()
  16. #表达式,and条件连接,逗号代表且操作
  17. # ret = session.query(Users).filter(Users.id > 7, Users.name == 'jason').all()
  18. # print(ret)between代表的是在3-5之间
  19. # ret = session.query(Users).filter(Users.id.between(3, 5), Users.name == 'jason').all()
  20. # print(ret)
  21. #注意下划线,in代表的是在这个区间之间
  22. # ret = session.query(Users).filter(Users.id.in_([1,3,4])).all()
  23. # print(ret)
  24. #~非,代表除。。外
  25. # ret = session.query(Users).filter(~Users.id.in_([1,3,4])).all()
  26. # print(ret)
  27.  
  28. # #二次筛选
  29. # ret = session.query(Users).filter(Users.id.in_(session.query(Users.id).filter_by(name='jason'))).all()
  30. # print(ret)
  31. from sqlalchemy import and_, or_
  32. #or_包裹的都是or条件,and_包裹的都是and条件
  33. #ret = session.query(Users).filter(and_(Users.id > 3, Users.name == 'eric')).all()
  34. # ret = session.query(Users).filter(or_(Users.id >6 , Users.name == 'jason')).all()
  35. # print(ret)
  36. # ret = session.query(Users).filter(
  37. # or_(
  38. # Users.id < 2,
  39. # and_(Users.name == 'eric', Users.id > 3),
  40. # Users.age != ""
  41. # )).all()
  42.  
  43. # 通配符like,以e开头,不以e开头,有_代表的是占位符,可以配合~
  44. # ret = session.query(Users).filter(Users.name.like('_q%')).all()
  45. # print(ret)
  46. # ret = session.query(Users).filter(~Users.name.like('j%')).all()
  47. # print(ret)
  48.  
  49. # 限制,用于分页,区间
  50. # ret = session.query(Users)[1:9]
  51. # print(ret)
  52. #
  53. # # 排序,根据name降序排列(从大到小)desc代表降序
  54. # ret = session.query(Users).order_by(Users.name.desc())
  55. # print(ret)
  56.  
  57. # #第一个条件重复后,再按第二个条件升序排,使用,隔开
  58. # ret = session.query(Users).order_by(Users.name.desc(), Users.id.asc())
  59. # print(ret)
  60. #
  61. # # 分组
  62. from sqlalchemy.sql import func
  63. # func需要风阻之后的输出
  64. # ret = session.query(Users).group_by(Users.name).all()
  65. # print(ret)
  66. # #分组之后取最大id,id之和,最小id
  67. # ret = session.query(
  68. # func.max(Users.id),
  69. # func.sum(Users.id),
  70. # func.min(Users.id)).group_by(Users.name).all()
  71. # print(ret)
  72. # #haviing筛选
  73. # ret = session.query(
  74. # # func.max(Users.id),
  75. # # func.sum(Users.id),
  76. # # func.min(Users.id)).group_by(Users.name).having(func.min(Users.id) >2)
  77. # # print(ret)

八。一对多查询。

  一对多建表:

  1. class Hobby(Base):
  2. __tablename__ = 'hobby'
  3. id = Column(Integer, primary_key=True)
  4. caption = Column(String(50), default='篮球')
  5.  
  6. class Person(Base):
  7. __tablename__ = 'person'
  8. nid = Column(Integer, primary_key=True)
  9. name = Column(String(32), index=True, nullable=True)
  10. # hobby指的是tablename而不是类名,
  11. hobby_id = Column(Integer, ForeignKey("hobby.id"))# 代表的是表明
  12. # 跟数据库无关,不会新增字段,只用于快速链表操作
  13. # 类名,backref用于反向查询,uselist=False
  14. hobby = relationship('Hobby', backref='pers') # 关联字段,不会生成字段,backref代表的是反向查询的时候的字段。
  15. def __repr__(self):
  16. return self.name

  一对多:

  1. import time
  2. import threading
  3.  
  4. from sqlalchemy.ext.declarative import declarative_base
  5. from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index
  6. from sqlalchemy.orm import sessionmaker, relationship
  7. from sqlalchemy import create_engine
  8. from sqlalchemy.sql import text
  9. from sqlalchemy.engine.result import ResultProxy
  10. from models import Users, Hobby, Person
  11.  
  12. engine = create_engine("mysql+pymysql://root:123@127.0.0.1:3306/flask?charset=utf8", max_overflow=0, pool_size=5)
  13. Session = sessionmaker(bind=engine)
  14. session = Session()
  15. # 添加
  16. # 1.不关联表的添加方法
  17. # session.add_all([
  18. # Hobby(caption='乒乓球'),
  19. # Hobby(caption='羽毛球'),
  20. # Person(name='张三', hobby_id=1),
  21. # Person(name='李四', hobby_id=2),
  22. # ])
  23. # 正向将hobby对象插入,可以自动关联
  24. # person = Person(name='张九', hobby=Hobby(caption='姑娘'))
  25. # session.add(person)
  26. #添加二,反向查询
  27. # hb = Hobby(caption='人妖')
  28. # hb.pers = [Person(name='文飞'), Person(name='博雅')]
  29. # session.add(hb)
  30. #
  31. # session.commit()
  32. """
  33.  
  34. # 使用relationship正向查询
  35. """
  36. # v = session.query(Person).first()
  37. # print(v.name)
  38. # print(v.hobby.caption)
  39. """
  40.  
  41. # 使用relationship反向查询
  42. """
  43. # v = session.query(Hobby).first()
  44. # print(v.caption)
  45. # print(v.pers)
  46.  
  47. #方式一,自己链表,isouter代表的是外联查询
  48. # person_list=session.query(Person).join(Hobby,isouter=True)
  49. # print(person_list)
  50. # person_list=session.query(Person,Hobby).join(Hobby,isouter=True)
  51. # print(person_list)
  52. # for row in person_list:
  53. # # print(row.name,row.caption)
  54. # print(row[0].name,row[1].caption)
  55. #
  56. # #方式二:通过relationship
  57. #
  58. person_list=session.query(Person).all()
  59. for row in person_list:
  60. print(row.name,row.hobby.caption)
  61. # #查询喜欢姑娘的所有人
  62. # obj=session.query(Hobby).filter(Hobby.id==1).first()
  63. # persons=obj.pers
  64. # print(persons)
  65. # session.close()
  66. #如果没有建立外键
  67.  
  68. # ret = session.query(Person).join(Hobby,Person.nid==Hobby.id, isouter=True)
  69. # print(ret)

九。多对多

  多对多建表

  1. class Boy2Girl(Base):
  2. __tablename__ = 'boy2girl'
  3. id = Column(Integer, primary_key=True, autoincrement=True)
  4. girl_id = Column(Integer, ForeignKey('girl.id'))
  5. boy_id = Column(Integer, ForeignKey('boy.id'))
  6.  
  7. class Girl(Base):
  8. __tablename__ = 'girl'
  9. id = Column(Integer, primary_key=True)
  10. name = Column(String(64), unique=True, nullable=False)
  11.  
  12. class Boy(Base):
  13. __tablename__ = 'boy'
  14.  
  15. id = Column(Integer, primary_key=True, autoincrement=True)
  16. hostname = Column(String(64), unique=True, nullable=False)
  17.  
  18. # 与生成表结构无关,仅用于查询方便,放在哪个单表中都可以
  19. girl = relationship('Girl', secondary='boy2girl', backref='boys')

  多对多

  1. import time
  2. import threading
  3.  
  4. from sqlalchemy.ext.declarative import declarative_base
  5. from sqlalchemy import Column, Integer, String, ForeignKey, UniqueConstraint, Index
  6. from sqlalchemy.orm import sessionmaker, relationship
  7. from sqlalchemy import create_engine
  8. from sqlalchemy.sql import text
  9. from sqlalchemy.engine.result import ResultProxy
  10. from models import Users, Hobby, Person, Girl, Boy2Girl, Boy
  11.  
  12. engine = create_engine("mysql+pymysql://root:123@127.0.0.1:3306/flask?charset=utf8", max_overflow=0, pool_size=5)
  13. Session = sessionmaker(bind=engine)
  14. session = Session()
  15. # 添加
  16.  
  17. # session.add_all([
  18. # Girl(name='c1.com'),
  19. # Girl(name='c2.com'),
  20. # Boy(hostname='A组'),
  21. # Boy(hostname='B组'),
  22. # ])
  23. # session.commit()
  24. #需要设置中间表建立联系
    # s2g = Boy2Girl(girl_id=1,boy_id=1)
  25. # session.add(s2g)
  26. # session.commit()
  27. #
  28. # 直接添加一个对象,设置改对象的外键值
  29. # gp = Girl(name='C组')
  30. # gp.boys = [Boy(hostname='c3.com'),Boy(hostname='c4.com')]
  31. # session.add(gp)
  32. # session.commit()
  33. #
  34. # 反向添加
  35. # ser = Boy(hostname='c6.com')
  36. # ser.girl = [Girl(name='F组'),Girl(name='G组')]
  37. # session.add(ser)
  38. # session.commit()
  39.  
  40. # 使用relationship正向查询
  41.  
  42. # v = session.query(Boy).first()
  43. # print(v.hostname)
  44. # print(v.girl)
  45.  
  46. # 使用relationship反向查询
  47.  
  48. # v = session.query(Girl).first()
  49. # print(v.name)
  50. # print(v.boys)
  51. #
  52. #
  53. #
  54. # session.close()

十。flask-SQLALchemy

  这是一个flask和SQLAchemy的管理者

  安装:

  1. pip install flask-sqlalchemy

  如果需要和django一样,迁移数据库文件,需要安装flask-migrate

  1. pip install flask-migrate

  项目结构:

  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3.  
  4. from flask import Blueprint
  5. from .. import db
  6. from .. import models
  7.  
  8. account = Blueprint('account', __name__)
  9.  
  10. @account.route('/login')
  11. def login():
  12. # db.session.add(models.Users(username='lqz', email='123'))
  13. # db.session.query(models.Users).all()
  14. # db.session.commit()
  15. # 添加示例
  16. """
  17. db.session.add(models.Users(username='lqz', pwd='123', gender=1))
  18. db.session.commit()
  19.  
  20. obj = db.session.query(models.Users).filter(models.Users.id == 1).first()
  21. print(obj)
  22.  
  23. PS: db.session和db.create_session
  24. """
  25. # db.session.add(models.Users(username='wupeiqi1', email='wupeiqi1@xx.com'))
  26. # db.session.commit()
  27. # db.session.close()
  28. #
  29. # db.session.add(models.Users(username='wupeiqi2', email='wupeiqi2@xx.com'))
  30. # db.session.commit()
  31. # db.session.close()
  32. # db.session.add(models.Users(username='alex1',email='alex1@live.com'))
  33. # db.session.commit()
  34. # db.session.close()
  35.  
  36. user_list = db.session.query(models.Users).all()
  37. db.session.close()
  38. for item in user_list:
  39. print(item.username)
  40.  
  41. return 'login'

sansa/views/account.py

  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3. from flask import Flask
  4. from flask_sqlalchemy import SQLAlchemy
  5. db = SQLAlchemy()
  6.  
  7. from .models import *
  8. from .views import account
  9.  
  10. def create_app():
  11. app = Flask(__name__)
  12. app.config.from_object('settings.DevelopmentConfig')
  13. # 将db注册到app中
  14. db.init_app(app)
  15. # 注册蓝图
  16. app.register_blueprint(account.account)
  17.  
  18. return app

sansa/__init__.py

  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3. from . import db
  4.  
  5. class Users(db.Model):
  6. """
  7. 用户表
  8. """
  9. __tablename__ = 'users'
  10. id = db.Column(db.Integer, primary_key=True)
  11. username = db.Column(db.String(80), unique=True, nullable=False)
  12. email = db.Column(db.String(120), unique=True, nullable=False)
  13. # ids = db.Column(db.Integer)
  14.  
  15. def __repr__(self):
  16. return '<User %r>' % self.username

sansa/models.py

  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3. """
  4. 生成依赖文件:
  5. pipreqs ./
  6.  
  7. """
  8. from sansa import create_app
  9. from flask_script import Manager
  10. from flask_migrate import Migrate,MigrateCommand
  11. from sansa import db
  12. app = create_app()
  13. manager=Manager(app)
  14. #为了实现迁移
  15. Migrate(app,db)
  16. #现在把命令注册进来
  17. manager.add_command('db1', MigrateCommand)
  18.  
  19. if __name__ == '__main__':
  20. # app.run()
  21. manager.run()

manage.py

  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3.  
  4. class BaseConfig(object):
  5. # SESSION_TYPE = 'redis' # session类型为redis
  6. # SESSION_KEY_PREFIX = 'session:' # 保存到session中的值的前缀
  7. # SESSION_PERMANENT = True # 如果设置为False,则关闭浏览器session就失效。
  8. # SESSION_USE_SIGNER = False # 是否对发送到浏览器上 session:cookie值进行加密
  9.  
  10. SQLALCHEMY_DATABASE_URI = "mysql+pymysql://root:123@127.0.0.1:3306/flask01?charset=utf8"
  11. SQLALCHEMY_POOL_SIZE = 5
  12. SQLALCHEMY_POOL_TIMEOUT = 30
  13. SQLALCHEMY_POOL_RECYCLE = -1
  14.  
  15. # 追踪对象的修改并且发送信号
  16. SQLALCHEMY_TRACK_MODIFICATIONS = False
  17.  
  18. class ProductionConfig(BaseConfig):
  19. pass
  20.  
  21. class DevelopmentConfig(BaseConfig):
  22. pass
  23.  
  24. class TestingConfig(BaseConfig):
  25. pass

settings.py

  启动迁移命令:

  1. python manage.py db1 init
  2. # 初始化init,没有表
  3. python manage.py db1 migrate
  4. # 设置表,相当于makemigrations
  5. python manage.py db1 upgrade
  6. #相当于migrate

  这样的设计就可以和django一样,操作表的字段了,所有操作都要找db

  补充:

  反向生成model文件:

  1. python manage.py inspectdb > app/models.py

day_92_11_14flask的启动和orm,反向生成model的更多相关文章

  1. SQLAlchemy 反向生成 model 模型

    前言 Django 反向生成的 model 模型的命令 :  python manager.py inspectdb SQLAlchemy / Flask-SQLAlchemy则是: pip3 ins ...

  2. 数据库已经存在表, django使用inspectdb反向生成model实体类

    1.通过inspectdb处理类,可以将现有数据库里的一个或者多个.全部数据库表生成Django model实体类 python manage.py inspectdb --database defa ...

  3. efcore dbfirst 通过数据库表反向生成model

    创建class library并设置为启动项目 使用nuget控制台,设置当前项目为新建的class library Install-Package Microsoft.EntityFramework ...

  4. python Django 之 Model ORM inspectdb(数据库表反向生成)

    在前一篇我们说了,mybatis-generator反向生成代码. 这里我们开始说如何在django中反向生成mysql model代码. 我们在展示django ORM反向生成之前,我们先说一下怎么 ...

  5. 数据库表反向生成(二) Django ORM inspectdb

    在前一篇我们说了,mybatis-generator反向生成代码. 这里我们开始说如何在django中反向生成mysql model代码. 我们在展示django ORM反向生成之前,我们先说一下怎么 ...

  6. 数据库和Django model 生成和反向生成

    Django 脚本生成数据表 建立映射关系 如果询问时区时间,选1 然后输入timezone.now() python manage.py makemigrations (如果有子应用的话子应用名称填 ...

  7. Django中反向生成models

    我们在展示django ORM反向生成之前,我们先说一下怎么样正向生成代码. 正向生成,指的是先创建model.py文件,然后通过django内置的编译器,在数据库如mysql中创建出符合model. ...

  8. 关于django操作orm的一些事--反向生成orm、连接多个数据库

    1. django反向生成orm的类代码 使用命令python manage.py inspectdb > app01/models.py,注意,我这里的app01是app的名字. 2.djan ...

  9. django 有model生成SQL以及现有反向表生成model

    已有models生成SQL语句 语法 python manage.py sqlall app_name   # app_name, 在settings已经导入, 如: INSTALLED_APPS = ...

随机推荐

  1. Unity 声音处理 之 语音识别

    音量检测 检测当前麦克风的输入音量 using System.Collections; using System.Collections.Generic; using UnityEngine; usi ...

  2. C# 使用 csc.exe 实现命令行生成

    概述 CSC是什么呢?CSC就是 C-Sharp Compiler (中文就是C#编译器),作用是把我们的 cs 源文件变异成dll 或者是exe ,    一般安装完VS 后,就会有这个文件: 这里 ...

  3. js中关于constructor与prototype的理解

    1.①__proto__和constructor属性是对象所独有的:② prototype属性是函数所独有的,因为函数也是一种对象,所以函数也拥有__proto__和constructor属性. 2. ...

  4. Geoserver安装

    准备内容 安装环境:win10*64位专业版 安装文件:geoserver-2.15.2 安装步骤 安装JDK 1.安装GeoServer是基于Java的环境,所以需要先装Jdk环境. 2.前往官网下 ...

  5. 51-overlay 是如何隔离的?

    不同的 overlay 网络是相互隔离的.我们创建第二个 overlay 网络 ov_net2 并运行容器 bbox3. bbox3 分配到的 IP 是 10.0.1.2,尝试 ping bbox1( ...

  6. 字典 dict方法

    字典 student = {'sId': '1101', 'sName': '张三', 'sClass': '软件测试', 'sColl': '信息技术学院'} # 根据键查询 若不存在会报错 pri ...

  7. RMAN RECOVER TABLE 功能是 Oracle Database 12c 的新增功能 (Doc ID 1521524.1)

    RMAN RECOVER TABLE Feature New to Oracle Database 12c (Doc ID 1521524.1) APPLIES TO: Oracle Database ...

  8. vue项目、路由

    目录 Vue项目创建 pycharm配置并启动vue项目 vue项目目录结构分析 js原型补充 vue项目生命周期 页面组件 配置自定义全局样式 路由逻辑跳转 路由重定向 组件的生命周期钩子 路由传参 ...

  9. [洛谷P1037][题解]产生数

    这道题的关键是利用Floyd算法的性质求转换方案,算是Floyd的一个变形,具体可以看代码. 题目 #include<bits/stdc++.h> using namespace std; ...

  10. JavaScript-----11.预解析

    1.预解析 1.1引子 //1问 console.log(num);//报错 num未定义 //2问 console.log(num); //undefined 未报错 var num = 10; / ...