Python learning, python

Source: Internet
Author: User

Python learning, python

In the previous article, the ORM (Object Relational Model) is implemented. This article mainly implements simple MySQL database operations.

To operate the database, you must first establish a database connection. The following defines a function for creating a database connection. A connection is called an engine.

def create_engine(user,password,database,host='127.0.0.1',port=3306,**kw):    import mysql.connector    global engine    if engine is not None:        raise DBError('Engine is already initialized.')    params = dict(user=user,password=password,database=database,host=host,port=port)    defaults = dict(use_unicode=True,charset='utf8',collation='utf8_general_ci',autocommit=False)    #print ('%s %s %s %s %s') % (user,password,database,host,port)    for k,v in defaults.iteritems():        params[k] = kw.pop(k,v)    params.update(kw)    params['buffered'] = True    engine = mysql.connector.connect(**params)    cursor = engine.cursor()

With the connection, you can operate the database. The following describes several functions that can be used to query and insert databases.

def _select(sql,first,*args):    cursor = None    sql = sql.replace('?','%s')    global engine    try:        cursor = engine.cursor()        cursor.execute(sql,args)        if cursor.description:            names = [x[0] for x in cursor.description]        if first:            values = cursor.fetchone()            if not values:                return None            return Dict(names,values)        return [Dict(names,x) for x in cursor.fetchall()]    finally:        if cursor:            cursor.close()def select_one(sql,*args):    return _select(sql,True,*args)def select(sql,*args):    return _select(sql,False,*args)def _update(sql,*args):    cursor = None    global engine    sql = sql.replace('?','%s')    print sql    try:        cursor = engine.cursor()        cursor.execute(sql,args)        r = cursor.rowcount        engine.commit()        return r    finally:        if cursor:            cursor.close()def insert(table,**kw):    cols, args = zip(*kw.iteritems())    sql = 'insert into %s (%s) values(%s)' % (table,','.join(['%s' % col for col in cols]),','.join(['?' for i in range(len(cols))]))    print ('sql %s args %s' % (sql, str(args)))    return _update(sql,*args)

By now, the basic database operations have been completed. However, according to Liao Xuefeng's tutorial, this is far from enough.

  • If you want to implement multiple operations in a database connection, the above code is very inefficient. If you do not execute a statement once, you need to allocate a new connection.
  • It is also inefficient to execute multiple operations in a transaction.
  • If the server assigns a thread for different user database requests to establish a connection, the connection is available in the process. As a result, database operations may be abnormal.

For the third problem, each connection should be owned by every thread, and other threads cannot be accessed, using threading. local. First, define a class to save the context of the database:

Class _ DbCtx (threading. local): def _ init _ (self): self. connection = None self. transactions = 0 def is_init (self): return not self. connection is None def init (self): self. connection = engine # create a database connection self. transactions = 0 def cleanup (self): self. connection. cleanup () self. connection = None def cursor (self): return self. connection. cursor ()

The above code has an error. Because the value assignment statement of Python only transmits an object reference to a variable, just like self. connection = engine in the init function in the code above. Indicates that both self. connection and engine point to a database connection object. If self. connection is given to cleanup, the object to which the engine points is also cleanup. Is an example:

A is a reference to a foo-like instance. After B = a is executed, B is executed. clean (). At this time, only the v value of B is changed to 0, but. the value of v also changes to 0.

The following is the final code, which only encapsulates the underlying database operations. The Code is also very popular, although it imitates Liao Xuefeng's code.

# -*- coding: utf-8 -*-import time, uuid, functools, threading, loggingclass Dict(dict):    '''    Simple dict but support access as x.y style.    '''    def __init__(self, names=(), values=(), **kw):        super(Dict, self).__init__(**kw)        for k, v in zip(names, values):            self[k] = v    def __getattr__(self, key):        try:            return self[key]        except KeyError:            raise AttributeError(r"'Dict' object has no attribute '%s'" % key)    def __setattr__(self, key, value):        self[key] = valueclass DBError(Exception):    passclass MultiColumnsError(Exception):    passengine = Noneclass _DbCtx(threading.local):    def __init__(self):        self.connection = None        self.transactions = 0    def is_init(self):        return not self.connection is None    def init(self):        self.connection = engine        self.transactions = 0    def cleanup(self):        self.connection = None        def cursor(self):        return self.connection.cursor()def create_engine(user,password,database,host='127.0.0.1',port=3306,**kw):    import mysql.connector    global engine    if engine is not None:        raise DBError('Engine is already initialized.')    params = dict(user=user,password=password,database=database,host=host,port=port)    defaults = dict(use_unicode=True,charset='utf8',collation='utf8_general_ci',autocommit=False)    #print ('%s %s %s %s %s') % (user,password,database,host,port)    for k,v in defaults.iteritems():        params[k] = kw.pop(k,v)    params.update(kw)    params['buffered'] = True    engine = mysql.connector.connect(**params)    print type(engine)_db_ctx = _DbCtx()class _ConnectionCtx(object):    def __enter__(self):        self.should_cleanuo = False        if not _db_ctx.is_init():            cursor = engine.cursor()            _db_ctx.init()            self.should_cleanup = True        return self    def __exit__(self,exctype,excvalue,traceback):        if self.should_cleanup:            _db_ctx.cleanup()def with_connection(func):    @functools.wraps(func)    def _wrapper(*args,**kw):        with _ConnectionCtx():            return func(*args, **kw)    return _wrapperdef _select(sql,first,*args):    cursor = None    sql = sql.replace('?','%s')    global _db_ctx    try:        cursor = _db_ctx.cursor()        cursor.execute(sql,args)        if cursor.description:            names = [x[0] for x in cursor.description]        if first:            values = cursor.fetchone()            if not values:                return None            return Dict(names,values)        return [Dict(names,x) for x in cursor.fetchall()]    finally:        if cursor:            cursor.close()@with_connectiondef select_one(sql,*args):    return _select(sql,True,*args)@with_connectiondef select_int(sql,*args):    d = _select(sql,True,*args)    if len(d) != 1:        raise MultoColumnsError('Except only one column.')    return d.values()[0]@with_connectiondef select(sql,*args):    global engine    print type(engine)    return _select(sql,False,*args)@with_connectiondef _update(sql,*args):    cursor = None    global _db_ctx     sql = sql.replace('?','%s')    print sql    try:        cursor = _db_ctx.cursor()        cursor.execute(sql,args)        r = cursor.rowcount        engine.commit()        return r    finally:        if cursor:            cursor.close()def insert(table,**kw):    cols, args = zip(*kw.iteritems())    sql = 'insert into %s (%s) values(%s)' % (table,','.join(['%s' % col for col in cols]),','.join(['?' for i in range(len(cols))]))    print ('sql %s args %s' % (sql, str(args)))    return _update(sql,*args)create_engine(user='root',password='z5201314',database='test')u1 = select_one('select * from user where id=?',1)print 'u1'print u1print 'start selet()...'u2 = select('select * from user')for item in u2:    print ('%s %s' % (item.name,item.id))print 'name:%s id: %s' % (u1.name,u1.id)

 


Who has the best Python tutorial?

There is no best tutorial. There are different tutorials at the same stage,
If you are a beginner, "Python basics" and "python learning manual" are good choices.
For more information, see Dive Into Python.
Cute Python introduces many python libraries, especially network programming.
To fully understand the python library, read the python standard library, which is very thick.
For practical classes, see python cookbook. You can learn a lot of skills and programming paradigm.
For the advanced stage, see python advanced programming.

For more information about how python works, see python source code analysis.
In the future, there will be a specialization in the industry. If you want to develop in any direction, read the relevant books.

I am a java developer. I want to transfer my software to the Internet. I want to learn python, teach me how to learn, and ask me what I recommend.

What are your goals for learning python?
If you write and write scripts at work to improve your work efficiency, you do not have to learn them with great fanfare.
We only learned how useful it can be. We recommend that you learn codecademy online. It is not an advertisement website. Baidu sousuo will know about it. It is a foreign online programming learning website that supports Chinese localization, there is a complete set of tutorials and exercises for learning python.
It is easy to learn this script language based on programming. If you have more exercises at work, find stackoverflow if you have any questions.

If you want to be proficient, it is hard to say that you are proficient in definition.
It may be a good choice to read the source code once you are familiar with it, or to read a book related to functional programming, such as SICP.

Related Article

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.