Advertisement
Guest User

Untitled

a guest
Jul 7th, 2015
191
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.80 KB | None | 0 0
  1. #!/usr/bin/env python
  2. # Copyright (c) 2012, Tim Henderson
  3. # All rights reserved.
  4. #
  5. # Redistribution and use in source and binary forms, with or without
  6. # modification, are permitted provided that the following conditions are
  7. # met:
  8. #
  9. # - Redistributions of source code must retain the above copyright notice,
  10. # this list of conditions and the following disclaimer.
  11. # - Redistributions in binary form must reproduce the above copyright
  12. # notice, this list of conditions and the following disclaimer in the
  13. # documentation and/or other materials provided with the distribution.
  14. # - Neither the name of this software nor the names of its contributors
  15. # may be used to endorse or promote products derived from this software
  16. # without specific prior written permission.
  17. #
  18. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  19. # IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  20. # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  21. # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  22. # HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23. # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
  24. # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  25. # PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  26. # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  27. # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  28. # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29.  
  30. """
  31. This module provides an "Upsert" statement for SQL Alchemy which uses
  32. ON DUPLICATE KEY UPDATE to implement the insert or update semantics. It
  33. supports doing a bulk insert.
  34. """
  35.  
  36. import sqlalchemy as sa
  37. from sqlalchemy.ext.compiler import compiles
  38.  
  39. class Upsert(expr.Insert): pass
  40.  
  41. @compiles(Upsert, "mysql")
  42. def compile_upsert(insert_stmt, compiler, **kwargs):
  43. if insert_stmt._has_multi_parameters:
  44. keys = insert_stmt.parameters[0].keys()
  45. else:
  46. keys = insert_stmt.parameters.keys()
  47. pk = insert_stmt.table.primary_key
  48. auto = None
  49. if (len(pk.columns) == 1 and
  50. isinstance(pk.columns.values()[0].type, sa.Integer) and
  51. pk.columns.values()[0].autoincrement):
  52. auto = pk.columns.keys()[0]
  53. if auto in keys:
  54. keys.remove(auto)
  55. insert = compiler.visit_insert(insert_stmt, **kwargs)
  56. ondup = 'ON DUPLICATE KEY UPDATE'
  57. updates = ', '.join(
  58. '%s = VALUES(%s)' % (c.name, c.name)
  59. for c in insert_stmt.table.columns
  60. if c.name in keys
  61. )
  62. if auto is not None:
  63. last_id = '%s = LAST_INSERT_ID(%s)' % (auto, auto)
  64. if updates:
  65. updates = ', '.join((last_id, updates))
  66. else:
  67. updates = last_id
  68. upsert = ' '.join((insert, ondup, updates))
  69. return upsert
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement