Flask "Third" using Dbutils to implement database connection pooling and blueprints

Source: Internet
Author: User
Tags connection pooling set time time interval

Small knowledge:

1. The subclass inherits three ways of the parent class

Class Dog (Animal): #子类  derived class    def __init__ (Self,name,breed, Life_value,aggr):        # animal.__init__ (Self,name, Breed, Life_value,aggr) #让子类执行父类的方法 is the name of the parent class. Method name (parameter), even self has to pass        super (). __init__ (NAME,LIFE_VALUE,AGGR) #super关键字  , there is no need to pass self, in the new class of        # Super (dog,self). __init__ (NAME,LIFE_VALUE,AGGR)  #上面super是简写        self.breed = Breed    def bite (Self,person):   #狗的派生方法        person.life_value-= Self.aggr    def eat (self):  # overriding super () of the parent class method        . Eat ()        print (' Dog is eating ')

2, the object through the index to set the value of three ways

Mode one: Overriding the __setitem__ method

Class Foo (object):    def __setitem__ (self, Key, value):        print (key,value) obj = Foo () obj["xxx"] = 123   # Assigning a value to an object will execute the __setitem__ method.

Way two: Inherit Dict

Class Foo (dict):    passobj = Foo () obj["xxx"] = 123print (obj)

Method Three: Inherit Dict, rewrite the __init__ method, remember to inherit the __init__ method of the parent class

Class Foo (Dict):    def __init__ (self,val):        # dict.__init__ (self, val) #继承父类方式一        # Super (). __init__ (Val)  #继承父类方式二        Super (Foo,self) __init__ (val) #继承父类方式三obj = Foo ({"XXX": 123}) print (obj)

Summary: If you encounter obj["xxx"] = XX, 

-Rewritten the __setitem__ method
-Inherit Dict

3. Test __name__ method

Example:

App1:    import app2    print (' App1 ', __name__) in APP2:    print (' app2 ', __name__)

Now App1 is the main program, running the result

Summary: If it is running in its own module, __name__ is __main__, if it is imported from another file, it is not __name__

I. Several ways to set up a configuration file

========== mode one: ============ app.config[' session_cookie_name '] = ' session_lvning '  #这种方式要把所有的配置都放在一个文件夹里面, Seems to be messy, so choose the following way ========== way two: ==============app.config.from_pyfile (' settings.py ')  #找到配置文件路径, create a module, open a file, And gets all the content, and then encapsulates all the values in the configuration file into the profile template created in the previous step

Print (App.config.get ("CCC"))
========= Way Three: The way of the object ============

os.environ[' flaks-settings '] = ' settings.py '


=============== mode Four (recommended): The way of the string, convenient operation, not to change the configuration, directly change the string on the line ==============
App.config.from_object (' Settings. DevConfig ')

----------settings. DevConfig----------
From app Import app
Class Baseconfig (object):
NNN = 123 #注意是大写
Session_cookie_name = "Session_sss"

Class Testconfig (Baseconfig):
DB = "127.0.0.1"

Class DevConfig (Baseconfig):
DB = "52.5.7.5"

Class Proconfig (Baseconfig):
DB = "55.4.22.4"


To get the value of a configuration file in a view function , it is taken by using App. Config. However, if the view function and the flask created object app are not in one module. will have to

Import to fetch. Can not be imported,. Directly import a Current_app, this is the current app object, with Current_app.config can see all the current app's configuration files

From flask Import Flask,current_app

@app. Route ('/index ', methods=["GET", "POST"]) def index ():    print (current_app.config)   #当前的app的所有配置    session["XX"] = "fdvbn"    Return "index"

Second, blueprint (flask in the multi-py file is used to split the blueprint)

If the code is very numerous, you want to categorize it. Different functions put in different files, bar related view functions are also put in. The blueprint is the allocation of the directory structure of the flask (applied to small, medium-sized programs),

Small Medium:

manage.py

Import fcrmif __name__ = = ' __main__ ':    fcrm.app.run ()

__init__.py (__init__.py file will be executed as soon as an import FCRM)

From flask import flask# importing accout and orderfrom fcrm.views import accoutfrom fcrm.views Import Orderapp = Flask (__name__) Print (App.root_path)  #根目录app. Register_blueprint (accout.accout)  #吧蓝图注册到app里面, Accout.accout is the Blueprint object created App.register_blueprint ( Order.order)

accout.py

From flask import  blueprint,render_templateaccout = Blueprint ("Accout", __name__) @accout. Route ('/accout ') def xx ( ):    return "Accout" @accout. Route ("/login") def login ():    return Render_template ("login.html")

order.py

From flask Import Blueprintorder = Blueprint ("Order", __name__) @order. Route ('/order ') def Register ():   # Note that the name of the view function cannot be the same as the name of the Blueprint object    return "order

What to look for when using blueprints

Large:

Third, database connection pool

There is no ORM in flask, if there are two ways to connect the database in flask

One: Pymysql two: SQLAlchemy        is a library of the Python operations database. The ability to perform an ORM mapping official document Sqlchemy        SQLAlchemy "uses the simple Python language for efficient and high-performance database access design, enabling a complete enterprise-class persistence model." SQLAlchemy's philosophy is that the magnitude and performance of SQL databases is important to object collections, and the abstraction of object collections is important for tables and rows.

Link Pooling principle

    -bdutils Database link Pool                  -mode one: Create a connection for each thread based on the threaing.local implementation, close is                  pseudo-shutdown, the current thread can repeat                -mode two: Connection pooling principle                        -you can set the maximum number of connections in the connection pool    9                        -The connection pool is created when the connection is started by default  5                                                -If there are three threads in the database                            to get the connection:-if three come at the same time, one person gives a link                            -if one comes, there is a time interval, Three threads can be serviced with a single link-it's impossible to say                                    that a link can serve three threads:                                    2 links can serve three threads it's possible:                                    3 links can serve three of threads                         PS,: maxshared is useless in the use of pymysql. Modules linked to a database: only useful when threadsafety>1

Then we'll do it with Pymysql.

Why use a database connection pool? What's so bad about not having a connection pool?

Method One, each operation to link the database, too many links

#!usr/bin/env python#-*-coding:utf-8-*-import pymysqlfrom  flask Import Flaskapp = Flask (__name__) # Way one: Every request in this way, Repeatedly creating database links, multiple links to the database can be time-consuming #        Workaround: Put in global, Singleton mode @app.route ('/index ') def index ():    # link Database    conn = Pymysql.connect ( Host= "127.0.0.1", port=3306,user= ' root ', password= ' 123 ', database= ' pooldb ', charset= ' UTF8 ')    cursor = Conn.cursor ()    cursor.execute ("SELECT * from TD where id=%s", [5,])    result = Cursor.fetchall ()  # Get Data    cursor.close ( )    Conn.close ()  # Close link    print (result)    return  "execution succeeded" if __name__ = = ' __main__ ':    app.run ( Debug=true)

Mode two, does not support concurrency

#!usr/bin/env python#-*-coding:utf-8-*-import pymysqlfrom  flask Import flaskfrom Threading Import Rlockapp = Flask ( __name__) CONN = Pymysql.connect (host= "127.0.0.1", port=3306,user= ' root ', password= ' 123 ', database= ' pooldb ', charset= ' UTF8 ') # Way two: Put in the global, if it is single-threaded, so you can, but if it is multi-threading, you have to add a lock. This is a serial #        does not support concurrency, nor is it good. All we choose to use the database connection pool @app.route ('/index ') def index (): With    rlock:        cursor = conn.cursor ()        cursor.execute (" SELECT * from TD where id=%s ", [5,])        result = Cursor.fetchall ()  # Get Data        cursor.close ()        print (Result)        return  "execution succeeded" if __name__ = = ' __main__ ':    app.run (debug=true)

Mode three: Because the above two options are not perfect, so you have to combine the way one and two (both to reduce the number of links, but also to support concurrency) all the way three, need

Import a dbutils module

There are two modes of database connection pooling that are implemented based on Dbutils:

Pattern One: Create a link for each thread (based on a local thread). thread.local), each thread independently uses its own database link, the thread shuts down not really close, when this thread is called again, or when the link that was created at the beginning is used, until the thread terminates and the database link closes

Note: Mode one: If the thread is more or will create a lot of connections, pattern two more common

#!usr/bin/env python#-*-coding:utf-8-*-from flask Import Flaskapp = Flask (__name__) from Dbutils.persistentdb import Per Sistentdbimport Pymysqlpool = Persistentdb (    creator=pymysql,  # module Maxusage=none using a linked database    ,  # The maximum number of times a link is reused, none means unrestricted    setsession=[],  # The list of commands executed before the session starts. such as: ["Set Datestyle to ...", "Set time zone ..."]    ping=0,    # Ping the MySQL server, check if the service is available. # for example: 0 = None = never, 1 = default = Whenever it is requested, 2 = When a cursor is created, 4 = When a query is executed, 7 =    always closeable=false,    # If False, Conn.close () is actually ignored for the next use, and the link is automatically closed when the thread is closed. If True, Conn.close () closes the link, and then calls Pool.connection again with an error, because the connection is actually closed (pool.steady_connection () can get a new link)    Threadlocal=none,  # This thread exclusive worth object, used to save the linked object, if the linked object is reset    host= ' 127.0.0.1 ',    port=3306,    user= ' root ',    password= ' 123 ',    database= ' pooldb ',    charset= ' UTF8 ') @app. Route ('/func ') def func ():
conn = Pool.connection ()
cursor = Conn.cursor ()
Cursor.execute (' select * from TB1 ')
result = Cursor.fetchall ()
Cursor.close ()
Conn.close () # is not really closed, but a fake off. conn = Pymysql.connect () conn.close ()

conn = Pool.connection ()
cursor = Conn.cursor ()
Cursor.execute (' select * from TB1 ')
result = Cursor.fetchall ()
Cursor.close ()
Conn.close ()
if __name__ = = ' __main__ ': App.run (debug=true)

Mode two: Create a link pool, provide connections for all threads, use to fetch, and put back to the connection pool when finished.

PS: Suppose the maximum number of links has 10, in fact, is a list, when you pop A, people will be in append a, link pool all the links are in line with the way to link.

All links in the link pool can be reused, shared, implemented concurrently, and prevented from linking too many times

Import timeimport pymysqlimport threadingfrom dbutils.pooleddb import pooleddb, Shareddbconnectionpool = PooledDB (Crea Tor=pymysql, # using the link database module maxconnections=6, # The maximum number of connections allowed by the connection pool, 0 and none means no limit to the number of connections mincached=2, # Initialization, at least the idle link created in the link pool, 0 means the non-invasive Build maxcached=5, # link pool up to idle links, 0 and none Limit maxshared=3, # The maximum number of links in the link pool to share, 0 and none means all share.    PS: Useless, because Pymysql and mysqldb modules such as threadsafety are 1, all values regardless of set to how much, _maxcached forever is 0, so forever is all links are shared. Blocking=true, # If there are no available connections in the connection pool, wait is blocked. True, wait, False, do not wait and then error maxusage=none, # The number of times a link is reused, None means unrestricted setsession=[], # The list of commands executed before the session starts. such as: ["Set Datestyle to ...", "Set time zone ..."] ping=0, # Ping the MySQL server, check if the service is available. # for example: 0 = None = never, 1 = default = Whenever it is requested, 2 = When a cursor is created, 4 = When a query is executed, 7 = always host= ' 127.0.0.1 ', port=3306, user= ' root ', password= ' 123 ', database= ' pooldb ', charset= ' UTF8 ') d EF func (): # Detects if the number of currently running connections is less than the maximum number of links, if not less than: Waits or reports raise Toomanyconnections exception # otherwise # gets the link in the link created when initializing Steadydbconnection.    # The Steadydbconnection object is then encapsulated in Pooleddedicateddbconnection and returned.    # If the link you initially created is not linked, then go to create a Steadydbconnection object and encapsulate it in pooleddedicateddbconnection and return.    # Once the link is closed, the connection is returned to the connection pool for subsequent threads to continue to use. # pooleddedicateddbconnection conn = pool.connection () # Print (th, ' link was taken away ', Conn1._con) # print (th, ' The pool is there now ', PO    Ol._idle_cache, ' \ r \ n ') cursor = Conn.cursor () cursor.execute (' select * from tb1 ') result = Cursor.fetchall () Conn.close () conn = Pool.connection () # Print (th, ' link was taken away ', Conn1._con) # print (th, ' The pool is now ', Pool._idle_cache, ' \ r \ n ') cursor = Conn.cursor () cursor.execute (' select * from tb1 ') result = Cursor.fetchall () conn.close () func ( )

Four, local thread: Ensure that each thread has its own data, in the operation will not affect others, even multi-threading, their values are isolated from each other

Before you use the thread

Import threading
Import time
Class Foo (object):    def __init__ (self):        self.name = Nonelocal_values = Foo () def func (num):    time.sleep (2)    local_values.name = num    print (Local_values.name,threading.current_thread (). Name) for I in range (5):    th = Threading. Thread (Target=func, args= (i,), name= ' thread%s '% i)    Th.start ()

Printing results:

1 thread 10 thread 02 thread 23 thread 34 thread 4

After using a local thread

Import threadingimport time# Local thread Object local_values = Threading.local () def func (num): ""    # The first thread comes in, and the local thread object creates a    # The second thread comes in, and the local thread object creates a    {        Unique identifier for thread 1: {name:1},        thread 2 unique identity: {name:2},    }    :p Aram Num:    : return:    "" "" Local_ Values.name = num # 4    # thread stopped.    time.sleep (2)    # Second thread: Local_values.name, go to local_values based on your unique identity as key, Gets the value of the name corresponding to    print (Local_values.name, Threading.current_thread (). Name) for I in range (5):    th = Threading. Thread (Target=func, args= (i,), name= ' thread%s '% i)    Th.start ()

Printing results:

1 thread 12 thread 20 thread 04 thread 43 Thread 3

V. Context Management

A, similar to a local thread, creates a native class: {' stack ': ' {' [request], ' xxx ': [Session,]},            The thread or the coprocessor uniquely identifies: {' stack ': []}, the thread or the coprocessor uniquely identifies: {' stack ': []}, the thread or the coprocessor uniquely identifies: {' stack ': []},            } b, the nature of context management each thread creates a structure like the one above, and when the request comes in, it adds the request-related data to the list [request,] and, if used later, reads                The data in the list, after the request is completed, remove the requests from the list C, the relationship local = ={thread or the coprocessor unique identity: {' stack ': []},            The thread or the coprocessor uniquely identifies: {' stack ': []}, the thread or the coprocessor uniquely identifies: {' stack ': []}, the thread or the coprocessor uniquely identifies: {' stack ': []}, stack = Strong Brother = {push Pop top} is based on strong brother to access things                Do d, recently read some flask source code, flask or Django some differences-flask and Django difference?                             -How to request the relevant data transfer-Django: is implemented by passing the request parameter-Flask: Based on the local object and the Localstark object. When the request has just come in the time to put in, finished top value on the line, take out after the pop walk on the line                                                Question: Will there be confusion over multiple requests-A: No, because, not only the thread, but also the association, each of the processes is uniquely identified:         From greenlent import Getcurrentt as Get_ident #这个就是来获取唯一标识的

Flask's request and session settings are relatively novel, if not this way, then can only pass the parameters.

How did the flask do it?

        -Local thread: is a thread created by flask itself (conjecture: is internal not based on a local thread?). )           Vals = Threading.local ()           def task (ARG):                vals.name = num            -Each thread comes in and prints its own, only its own ability to modify,            - By making sure that each thread has a database link, he can create the first pattern of the database link pool-The        context principle            -  similar to the local thread        -conjecture: is the interior not based on a local thread? No, it's a special dictionary.

#!/usr/bin/env python#-*-coding:utf-8-*-from functools import partialfrom flask.globals import LocalStack, LocalProxy l s = Localstack ()  class RequestContext (object):    def __init__ (self, environ):        self.request = Environ  def _lookup_req_object (name):    top = ls.top    if top is None:        raise RuntimeError (LS)    return getattr (top, Name)  session = Localproxy (partial (_lookup_req_object, ' request ')) Ls.push (RequestContext (' C1 ')) # When the request comes in, Put the print (session) # View function using the print (session) # View function using the Ls.pop () # Request to end pop  ls.push (requestcontext (' C2 ')) print (session) Ls.push (RequestContext (' C3 ')) print (session)

3. Flask Internal Implementation

#!/usr/bin/env python#-*-coding:utf-8-*-from Greenlet import getcurrent as Get_ident def release_local (local): Loc        AL.__RELEASE_LOCAL__ () class local (object): __slots__ = (' __storage__ ', ' __ident_func__ ') def __init__ (self):        # self.__storage__ = {} # self.__ident_func__ = Get_ident object.__setattr__ (self, ' __storage__ ', {}) Object.__setattr__ (self, ' __ident_func__ ', get_ident) def __release_local__ (self): Self.__storage__.pop (sel F.__ident_func__ (), None) def __getattr__ (self, name): Try:return self.__storage__[self.__ident_fun        C__ ()][name] except keyerror:raise attributeerror (name) def __setattr__ (self, Name, value):        Ident = self.__ident_func__ () storage = self.__storage__ Try:storage[ident][name] = value Except keyerror:storage[ident] = {Name:value} def __delattr__ (self, name): Try:del SE lf.__storage__[self.__idENT_FUNC__ ()][name] except keyerror:raise attributeerror (name) class Localstack (object): Def __init __ (self): self._local = local () def __release_local__ (self): self._local.__release_local__ () def pus H (self, obj): "" "pushes a new item to the stack" "rv = GetAttr (self._local, ' stack ', None) if RV is None:self._local.stack = RV = [] rv.append (obj) return rv def pop (self): "" "Removes t        He topmost item from the stack, would return the old value or ' None ' if the stack was already empty. "" "Stack = GetAttr (self._local, ' stack ', none) if Stack is None:return None elif Len (STA     CK) = = 1:release_local (self._local) return stack[-1] Else:return Stack.pop ()  @property def top (self): "", the topmost item on the stack.        If the stack is empty, ' None ' is returned.           "" "Try: return self._local.stack[-1] Except (Attributeerror, Indexerror): return None STC = Localstack () stc.p Ush (123) v = Stc.pop () print (v)

Flask "Third" using Dbutils to implement database connection pooling and blueprints

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.