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.