Guest User

Untitled

a guest
Nov 24th, 2017
160
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.02 KB | None | 0 0
  1. from tornado.gen import coroutine, Return, Task
  2.  
  3. import tormysql
  4. import tormysql.cursor
  5.  
  6. # noinspection PyUnresolvedReferences
  7. from pymysql import DatabaseError as DatabaseError
  8. from pymysql import OperationalError as ConnectionError
  9. from pymysql import IntegrityError as DuplicateError
  10. from pymysql import IntegrityError as ConstraintsError
  11.  
  12.  
  13. class DatabaseConnection(object):
  14. def __init__(self, conn):
  15. self.conn = conn
  16.  
  17. @coroutine
  18. def autocommit(self, value):
  19. yield self.conn.autocommit(value)
  20.  
  21. def close(self):
  22. self.conn.close()
  23.  
  24. @coroutine
  25. def commit(self):
  26. """
  27. Commits a non-autocommit cursor.
  28.  
  29. Usage:
  30.  
  31. with (yield db.acquire(auto_commit=False)) as db:
  32. row = yield db.get("SELECT ... FOR UPDATE");
  33. ...
  34. yield db.execute("UPDATE ...");
  35. yield db.commit()
  36.  
  37.  
  38. """
  39. yield self.conn.commit()
  40.  
  41. def rollback(self):
  42. return self.conn.rollback()
  43.  
  44. @coroutine
  45. def execute(self, query, *args, **kwargs):
  46. """
  47. Executes a mysql query.
  48. Used for 'UPDATE' and 'DELETE'
  49. """
  50.  
  51. with self.conn.cursor() as cursor:
  52. result = yield cursor.execute(query, args)
  53. raise Return(result)
  54.  
  55. @coroutine
  56. def get(self, query, *args, **kwargs):
  57. """
  58. Returns one row from a mysql query (a dict).
  59. Used for 'SELECT'.
  60. """
  61.  
  62. with self.conn.cursor() as cursor:
  63. yield cursor.execute(query, args)
  64. raise Return(cursor.fetchone())
  65.  
  66. @coroutine
  67. def insert(self, query, *args, **kwargs):
  68. """
  69. Inserts a new row into a mysql.
  70. Returns LAST_INSERT_ID, so used only for 'INSERT' queries.
  71. """
  72.  
  73. with self.conn.cursor() as cursor:
  74. yield cursor.execute(query, args)
  75. raise Return(cursor.lastrowid)
  76.  
  77. @coroutine
  78. def query(self, query, *args, **kwargs):
  79. """
  80. Returns all rows from a mysql query (a list of dicts, each dict represents a row).
  81. Used for 'SELECT'.
  82. """
  83.  
  84. with self.conn.cursor() as cursor:
  85. yield cursor.execute(query, args)
  86. raise Return(cursor.fetchall())
  87.  
  88. def __enter__(self):
  89. return self
  90.  
  91. def __exit__(self, *exc_info):
  92. del exc_info
  93. self.conn.close()
  94.  
  95.  
  96. class Database(object):
  97.  
  98. """
  99. Asynchronous MySQL database with connection pool.
  100. """
  101.  
  102. def __init__(self, host=None, database=None, user=None, password=None, *args, **kwargs):
  103. self.pool = tormysql.ConnectionPool(
  104. max_connections=256,
  105. wait_connection_timeout=5,
  106. idle_seconds=7200,
  107. host=host,
  108. db=database,
  109. user=user,
  110. passwd=password,
  111. cursorclass=tormysql.cursor.DictCursor,
  112. autocommit=True,
  113. use_unicode=True,
  114. charset="utf8",
  115. **kwargs
  116. )
  117.  
  118. @coroutine
  119. def acquire(self, auto_commit=True):
  120.  
  121. """
  122. Acquires a new connection from pool. Acquired connection has context management, so
  123. it can be used with 'with' statement, and few requests will happen in a single connection.
  124.  
  125. Usage:
  126.  
  127. with (yield db.acquire()) as db:
  128. yield db.get("...")
  129. yield db.insert("...")
  130.  
  131. """
  132.  
  133. wrapper = DatabaseConnection((yield self.pool.Connection()))
  134. yield wrapper.autocommit(auto_commit)
  135.  
  136. raise Return(wrapper)
  137.  
  138. @coroutine
  139. def execute(self, query, *args, **kwargs):
  140. """
  141. Executes a mysql query.
  142. Used for 'UPDATE' and 'DELETE'.
  143.  
  144. Please use 'acquire' method if you would like to make few requests in a row.
  145. """
  146.  
  147. with (yield self.acquire()) as conn:
  148. result = yield conn.execute(query, *args, **kwargs)
  149.  
  150. raise Return(result)
  151.  
  152. @coroutine
  153. def get(self, query, *args, **kwargs):
  154. """
  155. Returns one row from a mysql query (a dict).
  156. Used for 'SELECT'.
  157.  
  158. Please use 'acquire' method if you would like to make few requests in a row.
  159. """
  160.  
  161. with (yield self.acquire()) as conn:
  162. result = yield conn.get(query, *args, **kwargs)
  163.  
  164. raise Return(result)
  165.  
  166. @coroutine
  167. def insert(self, query, *args, **kwargs):
  168. """
  169. Inserts a new row into a mysql.
  170. Returns LAST_INSERT_ID, so used only for 'INSERT' queries.
  171.  
  172. Please use 'acquire' method if you would like to make few requests in a row.
  173. """
  174.  
  175. with (yield self.acquire()) as conn:
  176. result = yield conn.insert(query, *args, **kwargs)
  177.  
  178. raise Return(result)
  179.  
  180. @coroutine
  181. def query(self, query, *args, **kwargs):
  182. """
  183. Returns all rows from a mysql query (a list of dicts, each dict represents a row).
  184. Used for 'SELECT'.
  185.  
  186. Please use 'acquire' method if you would like to make few requests in a row.
  187. """
  188.  
  189. with (yield self.acquire()) as conn:
  190. result = yield conn.query(query, *args, **kwargs)
  191.  
  192. raise Return(result)
Add Comment
Please, Sign In to add comment