sqlalchemy

 

sqlalchemy-postgresql使用数据库连接池 

---用create_engine原生连接池写法

from psycopg2 import pool
from psycopg2 import Error
from sqlalchemy import text, create_engine


ENGINE_ = create_engine(
    "postgresql://{}:{}@{}:{}/{}".format(
        "testdb_name",
        "testdb_pwd",
        "localhost",
        "5432",
        "test_db_table_name"
    ),
    pool_size=20,
    max_overflow=10,
    echo=False,  # 这个参数,是打印sql执行日志
    pool_recycle=3600
)


def create_engine_pool_use(sql_statement):
    """
    用sqlalchemy原生的连接池,来操作数据库
    :param sql_statement: 传入的sql语句字符串
    :return:
    """
    engine_conn = ENGINE_.connect()
    result_ = engine_conn.execute(text(sql_statement))
    fetch_data = result_.fetchall()
    engine_conn.close()
    return fetch_data


# 使用方法。调用一次create_engine_pool_use方法,就是从连接池拿到一个连接,连接池只需要实例化一次
ret_db = create_engine_pool_use("select name from info_tb")
print(ret_db)

 

---用psycopg2封装连接池

class PostgresSQLPool:
    def __init__(self):
        """
        初始化配置
        """
        self.recursion_dict = {}
        try:
            self.connectPool = pool.ThreadedConnectionPool(
                2,
                10,
                host=InitConfig.POSTGRES_HOST,
                port=InitConfig.POSTGRES_PORT,
                user=InitConfig.POSTGRES_USER,
                password=InitConfig.POSTGRES_PWD,
                database=InitConfig.POSTGRES_DB,
                # 如下参数配置,是最底层被继承的Connect类的配置,适用于任何继承它的类
                keepalives_idle=10,  # 如果该连接闲置10s,就开始发送侦探包,轮训该连接是否有回应
                keepalives_count=3,  # 发送3个侦探包
                keepalives_interval=5  # 每次发送的侦探包,会等待5s。如果该连接
                # 闲置了10s,轮训了它3次,每次等待时间是5s,之后,它还是没有回应,就切断该连接
                )
        except (Exception, Error) as error:
            print("Error while connecting to PostgreSQL", error)
            raise EnvironmentError(str(error))

    def get_connect(self):
        """
        获取连接池连接对象
        :return: 
        """
        conn = self.connectPool.getconn()
        cursor = conn.cursor()
        return conn, cursor

    def close_connect(self, conn, cursor):
        """
        把从连接池拿到的连接,返回给连接池
        :param conn: 
        :param cursor: 
        :return: 
        """
        cursor.close()
        self.connectPool.putconn(conn)

    def close_all(self):
        """
        close all connection, if you call .close_all make sure your code
        can deal with it
        :return:
        """
        self.connectPool.closeall()

    def select_one(self, sql):
        """
        获取一条查询结果
        :param sql: sql sentence str
        :return:
        """
        conn, cursor = self.get_connect()
        cursor.execute(sql)
        result = cursor.fetchone()
        self.close_connect(conn, cursor)
        return result

    def select_all(self, sql):
        """
        获取所有查询结果
        :param sql: sql sentence str type
        :return:
        """
        conn, cursor = self.get_connect()
        cursor.execute(sql)
        result = cursor.fetchall()
        self.close_connect(conn, cursor)
        return result

    def execute_sql(self, sql_sentence, args=None):
        """
        execute add,delete,edit function
        :param sql_sentence:
        :param args:
        :return:
        """
        conn, cursor = self.get_connect()
        try:
            res = cursor.execute(sql_sentence, args)
            conn.commit(conn, cursor)
            self.close_connect(conn, cursor)
            return res
        except Exception as e:
            conn.rollback()
            raise ValueError("execute sql error. %s" % str(e))

    # 这里下面就是递归查询节点之间的调用关系方法,之前的项目中用到了,贴进来备忘
    @staticmethod
    def split_host_dep(tp_row):
        """
        depend each row of database selected to split host id、name、type and
        dep id、name、type
        :param tp_row:
        :return:
        """
        try:
            host_key = "**".join(tp_row[3:])
            dep_value = "**".join(tp_row[:3])
        except TypeError:
            # if field value selected is None, then replace it as ""
            each_key = ["" if each_field_value is None
                        else each_field_value
                        for each_field_value in tp_row]
            host_key = "**".join(each_key[3:])
            dep_value = "**".join(each_key[:3])
        return host_key, dep_value

    def recursion_db_select(self, host_key):
        """
        递归用sql语句查询,调试完成。
        :param host_key:查询关键字,string:id**name**type
        :return:
        """
        pdc_value = host_key.split("**")[0]
        sql_str = "select dep_pdc, dep_pdc_name, dep_pdc_type " \
                  " from" \
                  " tb_pdc_rel where host_pdc='%s';" % pdc_value
        ret = self.select_all(sql_str)
        if ret:
            # 如果有字节点,就继续递进去,查询字节点
            for each_row in ret:
                # host_value = each_row[0]
                host_value = "**".join(each_row)
                # 如果字节点不在存储最终数据的字典里,就创建一组键值对,键是id,值是空集合
                if host_key not in self.recursion_dict:
                    self.recursion_dict[host_key] = set()
                # 把当前递归层的元素,保存到最终存储的数据字典中
                self.recursion_dict[host_key].add(host_value)
                # 开始递到下一层
                ret_dic = self.recursion_db_select(host_value)
                if ret_dic:
                    # 如果有归回来的返回值,更新数据字典
                    self.recursion_dict.update(ret_dic)
        return self.recursion_dict

    def get_all_data(self):
        """
        get database all data
        :return:
        """
        sql_all_data = "select dep_pdc, dep_pdc_name, dep_pdc_type, " \
                       "host_pdc, host_pdc_name, host_pdc_type from" \
                       " tb_pdc_rel;"
        db_all_data = self.select_all(sql_all_data)
        # build all data to dict, key is host id**name**type, value is list of
        # dep id**name**type
        dic_obj = {}
        for each_key in db_all_data:
            host_key, dep_value = self.split_host_dep(each_key)
            if host_key not in dic_obj:
                dic_obj[host_key] = []
            dic_obj[host_key].append(dep_value)
        # rebuild data to dict, the key is host_pdc, the value is list
        # include all dep_pdc items
        return dic_obj

    def splice_id_name_type(self, id_value):
        """
        splice host id**name**type from database selected with the arg
        from for end transfer
        :param id_value:
        :return:
        """
        sql = "select host_pdc, host_pdc_name, host_pdc_type from tb_pdc_rel" \
              " where host_pdc='%s';" % id_value
        host_values = self.select_one(sql)
        if not host_values:
            raise ValueError("could not find any data from database")
        host_value = "**".join(host_values)
        return host_value

    def get_for_end_item_tree(self, host_value):
        """
        get all related data to prepare to render on html page
        :param host_value:host id**name**value from str
        :return:
        """
        dic_obj = self.get_all_data()
        recur_obj = RecursionTest()
        ret_dic = recur_obj.search_host_pdc(host_value, dic_obj)
        return ret_dic


# 使用方法
psql_obj = PostgresSQLPool()
ret = psql_obj.select_one("select name from info_table where id=10")
print(ret)
ret_all_db = psql_obj.select_all("select id, name from info_table")
print(ret_all_db)

 

  

  1 s8day128
  2 
  3 内容回顾:
  4     1. flask和django区别?
  5         - 相同:
  6             - 基于wsgi
  7         - 不同:
  8             - 传值方式
  9             - 组件:
 10                 - flask少
 11                 - django多
 12     
 13     2. flask上下文管理是如何实现?
 14         - 前提:记得不太清除了,应该是xxx; 前两天恰好刚看的。
 15         - 流程:
 16             - 请求刚进来,RequestContext(request,session)、AppContext(app,g) -> LocalStack -> Local 
 17             - 视图处理,LocalProxy -> 偏函数 -> LocalStack -> Local 
 18             - 请求结束,sava_session -> LocalStack.pop()
 19     
 20     3. Local作用?
 21         - 用于保存
 22             - 请求上下文对象
 23             - app上下文对象
 24         - 并且可以做到“线程”间的数据隔离。
 25         
 26         线程:threading.local
 27         协程:greenlet.get_current as get_ident
 28         
 29         
 30     4. LocalStack作用?
 31         - 将Local中保存的数据维护成一个栈
 32             
 33         {
 34             1432: { stack:[ctx,ctx,ctx,] }
 35         }
 36     
 37     5. Flask内置功能
 38         - 配置
 39         - 路由
 40         - 视图
 41         - 模板 
 42         - session
 43         - 蓝图
 44         - 闪现
 45         - 装饰器
 46         - 中间件
 47         
 48     6. 第三方组件:
 49         - Flask:
 50             - flask-session,将原来保存在cookie中的session数据,放到redis/memcache/文件/数据库中。
 51         - 公共:
 52             - DBUtils,数据库连接池
 53             - wtforms,做表单验证+生成HTML标签
 54 
 55 今日内容:
 56     1. 面向对象相关
 57         __mro__
 58         metaclass
 59         
 60     2. wtforms
 61     
 62     3. SQLALchemy/flask-sqlalchemy
 63     
 64     4. 其他
 65         - flask-script
 66         - flask-migrate
 67         - 多app应用
 68         - 离线脚本
 69     
 70 内容详细:
 71     1. 面向对象相关
 72         1. __mro__,找到当前类寻找属性的顺序。
 73             class A(object):
 74                 pass
 75 
 76 
 77             class B(A):
 78                 pass
 79 
 80 
 81             class C(object):
 82                 pass
 83 
 84             class D(B,C):
 85                 pass
 86 
 87             print(D.__mro__)
 88             
 89         2. __dict__
 90             class Foo(object):
 91                 CITY = 'bj'
 92                 def __init__(self,name,age):
 93                     self.name = name
 94                     self.age = age
 95                 def func(self):
 96                     pass
 97 
 98             # print(Foo.CITY)
 99             # print(Foo.func)
100             print(Foo.__dict__)
101 
102             obj1 = Foo('oldboy',54)
103             print(obj1.__dict__)
104         
105         3. metaclass
106             # 1. 创建类的两种方式
107             class Foo(object):
108                 CITY = "bj"
109 
110                 def func(self,x):
111                     return x + 1
112 
113             Foo = type('Foo',(object,),{'CITY':'bj','func':lambda self,x:x+1})
114         
115         
116                     
117             # 2. 类由自定义type创建
118             #    类由type创建,通过metaclass可以指定当前类由那一个type创建。
119             """
120             class MyType(type):
121                 def __init__(self,*args,**kwargs):
122                     print('创建类之前')
123                     super(MyType,self).__init__(*args,**kwargs)
124                     print('创建类之后')
125 
126             class Foo(object,metaclass=MyType): # 当前类,由type类创建。
127                 CITY = "bj"
128                 def func(self, x):
129                     return x + 1
130             """
131             # 3. 类的继承
132             #    类的基类中指定了metaclass,那么当前类也是由metaclass指定的类来创建当前类。
133             """
134             class MyType(type):
135                 def __init__(self,*args,**kwargs):
136                     print('创建类之前')
137                     super(MyType,self).__init__(*args,**kwargs)
138                     print('创建类之后')
139 
140             class Foo(object,metaclass=MyType): # 当前类,由type类创建。
141                 CITY = "bj"
142                 def func(self, x):
143                     return x + 1
144 
145             class Bar(Foo):
146                 pass
147             """
148 
149 
150             # ################################## 变 ##################################
151             """
152             class MyType(type):
153                 def __init__(self,*args,**kwargs):
154                     print('创建类之前')
155                     super(MyType,self).__init__(*args,**kwargs)
156                     print('创建类之后')
157 
158             Base = MyType('Base',(object,),{})
159             # class Base(object,metaclass=MyType):
160             #     pass
161 
162             class Foo(Base):
163                 CITY = "bj"
164                 def func(self, x):
165                     return x + 1
166             """
167             # ################################## 变 ##################################
168             """
169             class MyType(type):
170                 def __init__(self,*args,**kwargs):
171                     print('创建类之前')
172                     super(MyType,self).__init__(*args,**kwargs)
173                     print('创建类之后')
174 
175             def with_metaclass(arg):
176                 return MyType('Base',(arg,),{}) # class Base(object,metaclass=MyType): pass
177 
178             class Foo(with_metaclass(object)):
179                 CITY = "bj"
180                 def func(self, x):
181                     return x + 1
182             """
183 
184             # ######################################################## 实例化 ########################################################
185             class MyType(type):
186                 def __init__(self,*args,**kwargs):
187                     super(MyType,self).__init__(*args,**kwargs)
188 
189             class Foo(object,metaclass=MyType): # 当前类,由type类创建。
190                 pass
191 
192 
193             """
194             0. Mytype的__init__
195             obj = Foo() 
196             1. MyType的__call__
197             2. Foo的__new__
198             3. Foo的__init__
199             """
200             
201             总结:
202                 1. 默认类由type实例化创建。
203                 2. 某个类指定metaclass=MyType,那么当前类的所有派生类都由于MyType创建。
204                 3. 实例化对象
205                     - type.__init__ 
206                     
207                     - type.__call__
208                     - 类.__new__
209                     - 类.__init__
210                 
211         
212     2. wtforms实现流程
213         
214         实例化流程:
215             class LoginForm(Form):
216                 name = StringField(正则=[验证规则1,验证规则1,],插件=Input框)
217                 pwd = StringField(正则=[验证规则1,验证规则1,],插件=Password框)
218                 
219         
220         作业:找验证流程
221             
222         
223         相关面试题:
224             a. Python基础部分,哪些比较重要?
225                 - 反射
226                     - cbv
227                     - django 配置文件
228                     - wtforms中
229                         class Form(with_metaclass(FormMeta, BaseForm)):
230                         
231                             Meta = DefaultMeta
232 
233                             def __init__(self, formdata=None, obj=None, prefix='', data=None, meta=None, **kwargs):
234                             
235                                 ...
236                                 """
237                                 self._fields = {
238                                     'name': simple.StringField(实例化),
239                                     'pwd': simple.PasswordField(),
240                                 }
241                                 """
242                                 for name, field in iteritems(self._fields):
243                                     # Set all the fields to attributes so that they obscure the class
244                                     # attributes with the same names.
245                                     setattr(self, name, field)
246                                 ...
247                         obj = Form()
248                         obj.name 
249                 - 装饰器
250                     - flask路由 /装饰器
251                     - 认证
252                     - csrf
253                 
254                 - 生成器、迭代器
255                 
256                 
257                 - 面向对象
258                     - 继承、封装、多态
259                     - 特殊功能:
260                         - 双下划线的方法
261                             - __mro__ 
262                                 class FormMeta(type):
263                                 def __call__(cls, *args, **kwargs):
264                                     ...
265                                     # Create a subclass of the 'class Meta' using all the ancestors.
266                                     if cls._wtforms_meta is None:
267                                         bases = []
268                                         # LoginForm,Form,BaseForm,object
269                                         for mro_class in cls.__mro__:
270                                             if 'Meta' in mro_class.__dict__:
271                                                 bases.append(mro_class.Meta)
272 
273                                         cls._wtforms_meta = type('Meta', tuple(bases), {})
274                             - __dict__ 
275                                 - dir 
276                                 - dict 
277                             - __new__ ,实例化但是没有给当前对象
278                                 - wtforms,字段实例化时返回:不是StringField,而是UnboundField
279                                                 def __new__(cls, *args, **kwargs):
280                                                     if '_form' in kwargs and '_name' in kwargs:
281                                                         return super(Field, cls).__new__(cls)
282                                                     else:
283                                                         return UnboundField(cls, *args, **kwargs)
284                                 - rest framework ,many=True 
285                             - __call__
286                                 - flask请求的入口
287                                 - 字段生成标签时:字段.__str__ => 字段.__call__ => 插件.__call__ 
288                             - __iter__ 
289                                 pass
290                             
291                         - metaclass
292                             - 作用:用于指定使用哪个类来创建当前类
293                             - 场景:在类创建之前定制操作
294                                     示例:wtforms中,对字段进行排序。
295                 
296                 
297     3. SQLAchemy,ORM框架。
298         问题:什么是ORM?
299               关系对象映射
300                 类   ->301                 对象 -> 记录(一行数据)
302                 
303               当有了对应关系之后,不再需要编写SQL语句,取而代之的是操作:类、对象。
304                 ORM: models.User.objects.filter(id__gt=1,type__name='技术部')
305                 
306                 SQL: 
307                       select 
308                         id,
309                         name,
310                         age,
311                         email
312                       from user left join type on user.type_id = type.id 
313                         
314         问题: ORM和原生SQL哪个好?
315         
316         问题: 概念
317                 db first,根据数据库的表生成类
318                             django 
319                                 python manage.py inspectdb
320                 code first,根据类创建数据库表;
321                             django:
322                                 python manage.py makemigrations
323                                 python manage.py migrate 
324         
325         
326         问题:ORM是怎么实现?
327               DDD中: unit of work 
328         
329         
330         SQLALchemy,是一个基于python实现的ORM框架。
331             1. 基于SQLALchemy写原生SQL
332                 - SQLAclchemy连接池
333                     import time
334                     import threading
335                     import sqlalchemy
336                     from sqlalchemy import create_engine
337                     from sqlalchemy.engine.base import Engine
338                      
339                     engine = create_engine(
340                         "mysql+pymysql://root:123@127.0.0.1:3306/t1?charset=utf8",
341                         max_overflow=0,  # 超过连接池大小外最多创建的连接
342                         pool_size=5,  # 连接池大小
343                         pool_timeout=30,  # 池中没有线程最多等待的时间,否则报错
344                         pool_recycle=-1  # 多久之后对线程池中的线程进行一次连接的回收(重置)
345                     )
346                      
347                      
348                     def task(arg):
349                         conn = engine.raw_connection()
350                         cursor = conn.cursor()
351                         cursor.execute(
352                             "select * from t1"
353                         )
354                         result = cursor.fetchall()
355                         cursor.close()
356                         conn.close()
357                      
358                      
359                     for i in range(20):
360                         t = threading.Thread(target=task, args=(i,))
361                         t.start()
362                 - DBUtils+pymysql 做连接池
363             2. 基于SQLALchemy写ORM
364                 
365                 models.py 
366                     
367                     #!/usr/bin/env python
368                     # -*- coding:utf-8 -*-
369                     from sqlalchemy.ext.declarative import declarative_base
370                     from sqlalchemy import Column, Integer, String, UniqueConstraint, Index
371                     from sqlalchemy import create_engine
372 
373                     Base = declarative_base()
374 
375                     # 创建单表
376                     class Users(Base):
377                         __tablename__ = 'users'
378                         id = Column(Integer, primary_key=True,autoincrement=True)
379                         name = Column(String(32))
380                         extra = Column(String(16))
381                         
382                     
383                     # 数据库连接相关
384                     # engine = create_engine("mysql+pymysql://root:123456@127.0.0.1:3306/s8day128db?charset=utf8")
385                     # 创建表
386                     # Base.metadata.create_all(engine)
387                     # 删除表
388                     # Base.metadata.drop_all(engine)
389                         
390                 app.py 
391                     import models
392                     from sqlalchemy.orm import sessionmaker
393                     from sqlalchemy import create_engine
394 
395                     engine =create_engine("mysql+pymysql://root:123456@127.0.0.1:3306/s8day128db?charset=utf8")
396                     XXXXXX = sessionmaker(bind=engine)
397                     session = XXXXXX()
398 
399 
400 
401                     obj1 = models.Users(name="alex", extra='sb')
402                     obj2 = models.Users(name="alex", extra='db')
403                     session.add(obj1)
404                     session.add(obj2)
405 
406 
407                     session.commit()
408                                 
409         使用:
410             安装: pip3 install sqlalchemy
411             
412             
413             1. 表操作
414                     #!/usr/bin/env python
415                     # -*- coding:utf-8 -*-
416                     from sqlalchemy.ext.declarative import declarative_base
417                     from sqlalchemy import Column, Integer, String, UniqueConstraint, Index,DateTime,ForeignKey
418                     from sqlalchemy import create_engine
419                     import datetime
420                     Base = declarative_base()
421 
422                     class Classes(Base):
423                         __tablename__ = 'classes'
424                         id = Column(Integer, primary_key=True,autoincrement=True)
425                         name = Column(String(32),nullable=False,unique=True)
426 
427                     class Student(Base):
428                         __tablename__ = 'student'
429                         id = Column(Integer, primary_key=True, autoincrement=True)
430                         username = Column(String(32), nullable=False,index=True)
431                         password = Column(String(64), nullable=False)
432                         ctime = Column(DateTime,default=datetime.datetime.now)
433                         class_id = Column(Integer, ForeignKey("classes.id"))
434 
435                     class Hobby(Base):
436                         __tablename__ = 'hobby'
437                         id = Column(Integer, primary_key=True)
438                         caption = Column(String(50), default='篮球')
439 
440                     class Student2Hobby(Base):
441                         __tablename__ = 'student2hobby'
442                         id = Column(Integer, primary_key=True, autoincrement=True)
443                         student_id = Column(Integer, ForeignKey('student.id'))
444                         hobby_id = Column(Integer, ForeignKey('hobby.id'))
445 
446                         __table_args__ = (
447                             UniqueConstraint('student_id', 'hobby_id', name='uix_student_id_hobby_id'),
448                             # Index('ix_id_name', 'name', 'extra'),
449                         )
450 
451                     def init_db():
452                         # 数据库连接相关
453                         engine = create_engine("mysql+pymysql://root:123456@127.0.0.1:3306/s8day128db?charset=utf8")
454                         # 创建表
455                         Base.metadata.create_all(engine)
456                     def drop_db():
457                         engine = create_engine("mysql+pymysql://root:123456@127.0.0.1:3306/s8day128db?charset=utf8")
458                         # 删除表
459                         Base.metadata.drop_all(engine)
460 
461                     if __name__ == '__main__':
462                         # drop_db()
463                         init_db()
464             
465             2. 数据进行操作
466                 
467                 第一步:
468 469 470 471 472                 
473                 第二步:
474                     复杂查询条件
475                     分组
476                     排序
477                     连表
478                     分页
479                     组合union /union all 
480     
481     
482             PS: commit 
483             
484             参考博客:http://www.cnblogs.com/wupeiqi/articles/8259356.html
485     
486     
487 作业:
488     1. wtforms实例化过程
489     2. wtforms验证流程(钩子函数到底如何实现?)
490     3. SQLALchemy表+基本操作
491     
492     
493     
494     
495     
496     
497     
498     
499     
500     
501     
502     
503     
504     
505     
506     
507     
508     
509     
510     
511     
512     
513     
514     
515     
516     
517     
518     
519     
520     
概要

 

  1 s8day129
  2 
  3 内容回顾:
  4     1. 面试题准备
  5         a. 谈谈你对Python和其他语言的区别?
  6         b. 为什么要学python?
  7         c. 数据类型:
  8             - 字符串
  9             - 字典
 10             - 元组
 11             - 列表
 12             - 集合
 13             - collections
 14         d. 函数
 15             - 函数参数传递的是什么?
 16             - def func(a,b=[]):pass
 17             - lambda 表达式
 18             - 列表生成式   []
 19             - 生成器表达式 (for i in range(1))
 20             - 题: 
 21                 val = [lambda :i+1 for i in range(10)]
 22                 val[0]
 23                 data = val[0]()
 24                 print(data)
 25             - 常见内置函数:
 26                 - map
 27                 - reduce
 28                 - filter
 29                 - zip
 30                 - instance
 31                 - type
 32                 - 
 33             - 生成器、迭代器、装饰器
 34     2. 回顾
 35         - wtforms
 36         - SQLALchemy
 37         
 38         问题:
 39             a. wtforms作用?
 40             b. wtforms涉及到的知识点?哪里用了?
 41                 - metaclass
 42                 - 封装:UnboundField
 43                 - __new__
 44                 - __mro__
 45                 - setattr
 46                 - type(...)
 47             c. ORM和原生SQL比较?
 48                 
 49             d. 你用过的ORM框架有哪些?
 50             
 51             e. SQLAlchemy
 52                 - 数据库连接池
 53                 - 原生SQL
 54                 - ORM 
 55                     - 表操作
 56                         - 默认值
 57                         - 索引(联合索引,想要命中必须遵循“最左前缀”的规则)
 58                         - sqlalchemy中设置表:
 59                             - 引擎
 60                             - 编码
 61                     - 记录操作
 62                         - 增删改查
 63                     
 64 
 65 今日内容:
 66     1. wtforms验证流程
 67     
 68     """
 69         处理插入新数据的视图:
 70             GET请求:
 71                 form = Form()
 72             POST请求:
 73                 form = From(formdata=表单提交的数据)
 74                 form.validate()
 75 
 76         处理更新数据的视图:
 77             GET请求:
 78                 查出obj, 保存住在后续POST请求还要用
 79                 form = Form(obj = obj)
 80             POST请求
 81                 form = Form(formdata=表单提交的数据,obj=obj)
 82                 form.validate()
 83 
 84         其他情况视图:
 85             form = Form(data={ .. })
 86             # data作为表单的默认value
 87     """
 88     
 89     
 90     2. sqlalchemy
 91         - relationship
 92         - 子查询
 93         
 94     问题:
 95         1. sqlalchemy中设置表:引擎、编码
 96         2. django的db first示例
 97     
 98     
 99 内容详细:
100     1. wtforms验证流程
101     
102     
103     
104     2. SQLAlchemy
105         - relationship作用?增加和查询
106             
107             
108             一对多:
109                 class UserType(Base):
110                     __tablename__ = 'usertype'
111                     id = Column(Integer, primary_key=True)
112                     caption = Column(String(50), default='管理员')
113 
114 
115                 class Person(Base):
116                     __tablename__ = 'person'
117                     nid = Column(Integer, primary_key=True)
118                     name = Column(String(32), index=True, nullable=True)
119                     hobby_id = Column(Integer, ForeignKey("usertype.id"))
120 
121                     # 与生成表结构无关,仅用于查询方便
122                     hobby = relationship("UserType", backref='pers')
123                     
124                 数据添加:
125                     session.add(UserType(caption='超级管理员'))
126                     session.commit()
127                     
128                     session.add(Person(name='翔龙',hobby_id=1))
129                     session.commit()
130         
131         
132                     session.add(Person(name='小韩',hobby=UserType(cation='VVIP')))
133                     session.commit()
134                 
135                 数据查询:
136                     正向操作:
137                         obj = session.query(Person).filter(Person.nid==2).first()
138                         obj.hobby.caption
139                     反向操作:
140                         obj = session.query(UserType).filter(UserType.id==1).first()
141                         obj.pers
142             多对多:
143                 class User2Hobby(Base):
144                     __tablename__ = 'user2hobby'
145                     id = Column(Integer, primary_key=True, autoincrement=True)
146                     hobby_id = Column(Integer, ForeignKey('hobby.id'))
147                     user_id = Column(Integer, ForeignKey('user.id'))
148 
149 
150                 class Hobby(Base):
151                     __tablename__ = 'hobby'
152                     id = Column(Integer, primary_key=True)
153                     title = Column(String(64), unique=True, nullable=False)
154 
155                     # 与生成表结构无关,仅用于查询方便
156                     users = relationship('User', secondary='user2hobby', backref='hbs')
157 
158 
159                 class User(Base):
160                     __tablename__ = 'user'
161 
162                     id = Column(Integer, primary_key=True, autoincrement=True)
163                     name = Column(String(64), unique=True, nullable=False)
164 
165                     
166                 添加数据:
167                     session.add(Hobby(title='篮球'))
168                     session.commit()
169                     
170                     session.add(User(name='梅凯'))
171                     session.commit()
172                     
173                     session.add(User2Hobby(hobby_id=1,user_id=1))
174                     session.commit()
175                     
176                     
177                     obj = Hobby(title='篮球')
178                     obj.servers = [User(name='王岩'),User(name='晓梅')]
179                     session.add(obj)
180                     session.commit()
181                     
182                     
183                     obj = User(title='俊杰')
184                     obj.hbs = [Hobby(title='翔龙'),Hobby(title='兴隆')]
185                     session.add(obj)
186                     session.commit()
187                 查询:
188                     obj = session.query(User).filter(User.id==2).first()
189                     obj.hbs
190                     
191                     obj = session.query(Hobby).filter(Hobby.id==2).first()
192                     obj.users
193                     
194         - SQL 
195             
196             a. 
197                 select * from A where id in (select age from B)
198             b. 
199                 select 
200                     id,
201                     name,
202                     1
203                 from A
204                 
205                 
206                 select 
207                     id,
208                     name,
209                     1,
210                     (select max(id) from B) as b
211                 from A
212                 
213                 
214                 
215                 select 
216                     id,
217                     name,
218                     1,
219                     (select max(id) from B where B.xid=A.id) as b
220                 from A
221                 
222                     +----+---------------+
223                     | id | name          |
224                     +----+---------------+
225                     |  1 | 全栈1期099    |
226                     |  2 | 全栈2期099    |
227                     +----+---------------+
228                     
229                     +----+---------+
230                     | id | caption |   xid
231                     +----+---------+
232                     |  1 | 篮球    |    1
233                     |  2 | 球      |    1
234                     +----+---------+
235                 
236                 subqry = session.query(func.count(Server.id).label("sid")).filter(Server.id == Group.id).correlate(Group).as_scalar()
237                 result = session.query(Group.name, subqry)
238                 """
239                 SELECT 
240                     `group`.name AS group_name, 
241                     (SELECT count(server.id) AS sid FROM server  WHERE server.id = `group`.id) AS anon_1 
242                 FROM `group`
243                 """
244 
245                 
246                 
247                 # 也可以使用原生SQL
248                 """
249                 # 查询
250                 cursor = session.execute('select * from users')
251                 result = cursor.fetchall()
252 
253                 # 添加
254                 cursor = session.execute('insert into users(name) values(:value)',params={"value":'wupeiqi'})
255                 session.commit()
256                 print(cursor.lastrowid)
257                 """
258                 
259                 
260                 扩展:
261                     select 
262                     id,
263                     name,
264                     1,
265                     (select max(id) from B where B.xid=A.id) as b # 生物课
266                     (select max(id) from B where B.xid=A.id) as b # 物理课
267                 from A
268                 
269                 where 
270                      生物课 》 物理课
271                 
272     
273                 复习:
274                     http://www.cnblogs.com/wupeiqi/articles/5729934.html
275                     
276                     http://www.cnblogs.com/wupeiqi/articles/5748496.html
277             
278     
279     
280 
281 作业:
282     
283     问题:
284         1. sqlalchemy中设置表:引擎、编码
285         2. django的db first示例
286         3. 在基于蓝图的Flask程序应用SQLAlchemy,示例:用户登录
287         
288         
289     
290     
291     
292     
293     
294     
295     
296     
297     
298     
299     
300     
301     
302     
303     
304     
305     
306     
307     
308     
309     
310     
311     
312     
313     
314     
315     
316         
概要2

 

参详博客地址:点这里

还有这里

先把地方霸占着

sqlalchemy数据增删改查以及创建表和删除表

 1 from sqlalchemy.ext.declarative import declarative_base
 2 from sqlalchemy import Column, Integer, String, UniqueConstraint, ForeignKey, Index, DateTime
 3 from sqlalchemy import create_engine
 4 from sqlalchemy.orm import relationship
 5 import datetime
 6 
 7 Bar = declarative_base()
 8 
 9 
10 class Classes(Bar):
11     __tablename__ = 'class'
12     id = Column(Integer, primary_key=True, autoincrement=True)
13     cname = Column(String(20), nullable=False, unique=True)
14 
15 
16 class Student(Bar):
17     __tablename__ = 'student'
18     id = Column(Integer, primary_key=True, autoincrement=True)
19     sname = Column(String(20), nullable=False, index=True)  # index是建立普通索引
20     ctime = Column(DateTime, default=datetime.datetime.now)  # 这里我们不能加(),在编译的过程中会自动加上,
21     # 如果我们在这里加上之后就会以程序启动的时间为当前时间,并且固定在这里了,不会自动切换了
22     lesson_id = Column(Integer, ForeignKey('class.id'))  # 外键关联的字段用表名.字段名的格式
23     sc = relationship('Classes', backref='stcs')
24 
25 
26 class Hobby(Bar):
27     __tablename__ = 'hobby'
28     id = Column(Integer, primary_key=True, autoincrement=True)
29     title = Column(String(20), default='sing the song')
30 
31 
32 class Stuent2Hobby(Bar):
33     __tablename__ = 'sts2ho'
34     id = Column(Integer, primary_key=True, autoincrement=True)
35     student_id = Column(Integer, ForeignKey('student.id'))
36     hobby_id = Column(Integer, ForeignKey('hobby.id'))
37 
38     __table_args__ = (
39         UniqueConstraint('student_id', 'hobby_id', name='uix_student_id_hobby_id'),
40     )  # 这里是创建联合唯一索引,就相当于我们的mysql里面的index('ix_id_name','name','extra'),
41 
42 
43 class Person(Bar):
44     __tablename__='person'
45     id=Column(Integer,primary_key=True,autoincrement=True)
46     age=Column(Integer)
47     name=Column(String(20),nullable=True)
48 
49 def init_a():
50     xxx = create_engine('mysql+pymysql://root:123@127.0.0.1:3306/book_list?charset=utf8')
51     Bar.metadata.create_all(xxx)
52 
53 
54 def drop_b():
55     aaa = create_engine('mysql+pymysql://root:123@127.0.0.1:3306/book_list?charset=utf8')
56     Bar.metadata.drop_all(aaa)
57 
58 
59 if __name__ == '__main__':
60     init_a()
61     # drop_b()
多表关系
 1 from sqlalchemy.ext.declarative import declarative_base
 2 from sqlalchemy import Column, Integer, String
 3 from sqlalchemy import create_engine
 4 
 5 Model_Base = declarative_base()
 6 
 7 
 8 # 创建表单
 9 class Users(Model_Base):
10     __tablename__ = 'usertable'
11     id = Column(Integer, primary_key=True, autoincrement=True)
12     name = Column(String(20))
13     pwd = Column(String(14))
14     __table_args__ = {
15         'mysql_charset': 'utf8',
16         'mysql_engine': 'InnoDB',
17     }
18 
19 
20 def init_db():
21     engine = create_engine('mysql+pymysql://root:123@127.0.0.1:3306/book_list?charset=utf8')
22     Model_Base.metadata.create_all(engine)
23 
24 
25 def drop_db():
26     engine = create_engine('mysql+pymysql://root:123@127.0.0.1:3306/book_list?charset=utf8')
27     Model_Base.metadata.drop_all(engine)
28 
29 
30 if __name__ == '__main__':
31     init_db()
32     # drop_db()  # 创建关联表的时候,不能这样直接用我们的drop_all去删除,有坑,会报错
33 #  还有我们在这里执行完表格的创建和删除之后要到我们的mysql数据库里面去查询结果
单表

 

1 from sqlalchemy import create_engine
2 engine=create_engine('mysql+pymysql://root:123@127.0.0.1:3306/book_list?charset=utf8')
3 obj=engine.execute('select name from loginuser')
4 result=obj.fetchall()
5 print(result)  # [('peter',), ('eval',)] 连接成功
mysql回顾

 

 1 from sqlalchemy_demo.sqlalchemy.models import Users
 2 from sqlalchemy import create_engine
 3 from sqlalchemy.orm import sessionmaker
 4 engine=create_engine('mysql+pymysql://root:123@127.0.0.1:3306/book_list?charset=utf8')
 5 www=sessionmaker(bind=engine)
 6 session=www()
 7 
 8 oh=Users(name='peter',pwd='213')
 9 ow=Users(name='wusir',pwd=123)
10 session.add(oh)
11 session.add(ow)
12 session.commit()
单表操作

 

 1 from sqlalchemy_demo.sqlalchemy import model
 2 from sqlalchemy.orm import sessionmaker
 3 from sqlalchemy import create_engine,text
 4 from sqlalchemy.sql import func
 5 connect=create_engine("mysql+pymysql://root:123@127.0.0.1:3306/book_list?charset=utf8")
 6 ses=sessionmaker(bind=connect)
 7 session=ses()
 8 
 9 # 添加多条数据
10 # obj=[
11 #     model.Classes(cname='python2period'),
12 #     model.Classes(cname='python1period'),
13 #     model.Classes(cname='python3period')
14 #      ]
15 # session.add_all(obj)
16 # session.commit()
17 
18 # 查询
19 # ret=session.query(model.Classes).all()
20 # for i in ret:
21 #     print(i.id,i.cname)
22 
23 # 删除
24 # session.query(model.Classes).filter(model.Classes.id>15).delete()
25 # session.commit()
26 
27 # change/update
28 # session.query(model.Classes).filter(model.Classes.cname=='web').update({model.Classes.cname:'web_flask'})  # 直接赋值的方法修改
29 # session.query(model.Person).filter(model.Person.id>0).update({'age':model.Person.age-20},synchronize_session='evaluate')
30 # 这里我们的参数里面设置的synchronize_session='evaluate' 得到的是数字之间的运算结果,我们如果要修改数据库中的数字类型的话
31 
32 # session.query(model.Classes).filter(model.Classes.id>5).update({'cname':model.Classes.cname+'hello'},synchronize_session=False)
33 # 这个参数的值设置为False,我们就得到的是字符串的拼接,
34 
35 # 关联查询
36 ret=session.query(model.Classes).filter(model.Classes.id.in_(session.query(model.Classes.id).filter_by(cname='javahello'))).all()
37 obj=session.query(model.Classes).from_statement(text("SELECT * FROM class where cname=:name")).params(name='javahello').first()
38 # print(obj)
39 
40 rea=session.query(func.count(model.Classes.id).label('cid')).filter(model.Student.id==model.Classes.id).correlate(model.Classes).as_scalar()
41 result=session.query(model.Classes.cname,rea)
42 print(result)
43 """
44 得到的result是sql语句,细细体会吧.
45 
46 SELECT class.cname AS class_cname, (SELECT count(class.id) AS cid 
47 FROM student 
48 WHERE student.id = class.id) AS anon_1 
49 FROM class
50 """
51 
52 session.commit()
53 session.close()
多表操作

 

 

=======================================================================================================================================

 1 """
 2 这里是源码里面的逻辑代码
 3 
 4 session = scoped_session对象 {
 5     session_factory = XXXXXX,
 6     registry = ThreadLocalRegistry{
 7         createfunc=XXXXXX,
 8         registry=threading.local()
 9     }
10 }
11 
12 class  scoped_session:
13     def add(self, *args, **kwargs):
14         return getattr(self.registry(), 'add')(*args, **kwargs)
15 
16     def add_all(self, *args, **kwargs):
17         return getattr(self.registry(), 'add_all')(*args, **kwargs)
18 
19     def commit(self, *args, **kwargs):
20         return getattr(self.registry(), 'commit')(*args, **kwargs)
21 
22     def query(self, *args, **kwargs):
23         return getattr(self.registry(), 'query')(*args, **kwargs)
24 """
25 
26 
27 from sqlalchemy_demo.sqlalchemy.model import *
28 from threading import Thread
29 from sqlalchemy.orm import sessionmaker,scoped_session
30 from sqlalchemy import create_engine
31 
32 engine = create_engine('mysql+pymysql://root:123@127.0.0.1:3306/book_list?charset=utf8', pool_size=3, max_overflow=0)
33 qqx = sessionmaker(bind=engine)
34 sess = scoped_session(qqx)
35 
36 """
37 我们的sessionmaker实例化出来的对象在这里可以自定义,然后我们就用这个自定义的对象去数据库获取数据对象
38 """
39 
40 
41 def whh():
42     data = sess.query(Classes).filter(Classes.id>14).first()
43     # for i in data:
44     #     print(i.id, i.cname)
45     print(data, type(data))
46     sess.remove()
47 
48 
49 for i in range(5):
50     a = Thread(target=whh)
51     a.start()
看不懂就算了吧...
 1 from sqlalchemy_demo.sqlalchemy.model import *
 2 from threading import Thread
 3 from sqlalchemy.orm import sessionmaker
 4 from sqlalchemy import create_engine
 5 
 6 engine = create_engine('mysql+pymysql://root:123@127.0.0.1:3306/book_list?charset=utf8', pool_size=3, max_overflow=0)
 7 qqx = sessionmaker(bind=engine)
 8 sess = qqx()
 9 
10 """
11 我们的sessionmaker实例化出来的对象在这里可以自定义,然后我们就用这个自定义的对象去数据库获取数据对象
12 """
13 
14 
15 def whh():
16     data = sess.query(Classes).all()
17     for i in data:
18         print(i.id, i.cname)
19     # print(data, type(data))
20     sess.close()
21 
22 
23 for i in range(5):
24     a = Thread(target=whh)
25     a.start()
同上啊

 

posted @ 2018-05-06 16:49  dream-子皿  阅读(251)  评论(0)    收藏  举报