v.db.dropcolumn.py 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. #!/usr/bin/env python3
  2. ############################################################################
  3. #
  4. # MODULE: v.db.dropcolumn
  5. # AUTHOR(S): Markus Neteler
  6. # Converted to Python by Glynn Clements
  7. # PURPOSE: interface to db.execute to drop a column from the
  8. # attribute table connected to a given vector map
  9. # - Based on v.db.addcolumn
  10. # - with special trick for SQLite
  11. # COPYRIGHT: (C) 2007 by the GRASS Development Team
  12. #
  13. # This program is free software under the GNU General Public
  14. # License (>=v2). Read the file COPYING that comes with GRASS
  15. # for details.
  16. #
  17. #############################################################################
  18. # %module
  19. # % description: Drops a column from the attribute table connected to a given vector map.
  20. # % keyword: vector
  21. # % keyword: attribute table
  22. # % keyword: database
  23. # %end
  24. # %option G_OPT_V_MAP
  25. # % key: map
  26. # %end
  27. # %option G_OPT_V_FIELD
  28. # %end
  29. # %option G_OPT_DB_COLUMNS
  30. # % description: Name of attribute column(s) to drop
  31. # % required: yes
  32. # %end
  33. import string
  34. import grass.script as grass
  35. from grass.exceptions import CalledModuleError
  36. def main():
  37. map = options["map"]
  38. layer = options["layer"]
  39. columns = options["columns"].split(",")
  40. mapset = grass.gisenv()["MAPSET"]
  41. # does map exist in CURRENT mapset?
  42. if not grass.find_file(map, element="vector", mapset=mapset)["file"]:
  43. grass.fatal(_("Vector map <%s> not found in current mapset") % map)
  44. f = grass.vector_layer_db(map, layer)
  45. table = f["table"]
  46. keycol = f["key"]
  47. database = f["database"]
  48. driver = f["driver"]
  49. if not table:
  50. grass.fatal(
  51. _(
  52. "There is no table connected to the input vector map. "
  53. "Unable to delete any column. Exiting."
  54. )
  55. )
  56. if keycol in columns:
  57. grass.fatal(
  58. _(
  59. "Unable to delete <%s> column as it is needed to keep table <%s> "
  60. "connected to the input vector map <%s>"
  61. )
  62. % (keycol, table, map)
  63. )
  64. for column in columns:
  65. if column not in grass.vector_columns(map, layer):
  66. grass.warning(
  67. _("Column <%s> not found in table <%s>. Skipped") % (column, table)
  68. )
  69. continue
  70. if driver == "sqlite":
  71. # echo "Using special trick for SQLite"
  72. # http://www.sqlite.org/faq.html#q11
  73. colnames = []
  74. coltypes = []
  75. for f in grass.db_describe(table, database=database, driver=driver)["cols"]:
  76. if f[0] == column:
  77. continue
  78. colnames.append(f[0])
  79. # see db_sqltype_name() for type names
  80. if f[1] == "CHARACTER":
  81. # preserve field length for sql type "CHARACTER"
  82. coltypes.append("%s %s(%s)" % (f[0], f[1], f[2]))
  83. else:
  84. coltypes.append("%s %s" % (f[0], f[1]))
  85. colnames = ", ".join(colnames)
  86. coltypes = ", ".join(coltypes)
  87. cmds = [
  88. "BEGIN TRANSACTION",
  89. "CREATE TEMPORARY TABLE ${table}_backup (${coldef})",
  90. "INSERT INTO ${table}_backup SELECT ${colnames} FROM ${table}",
  91. "DROP TABLE ${table}",
  92. "CREATE TABLE ${table}(${coldef})",
  93. "INSERT INTO ${table} SELECT ${colnames} FROM ${table}_backup",
  94. "CREATE UNIQUE INDEX ${table}_cat ON ${table} (${keycol} )",
  95. "DROP TABLE ${table}_backup",
  96. "COMMIT",
  97. ]
  98. tmpl = string.Template(";\n".join(cmds))
  99. sql = tmpl.substitute(
  100. table=table, coldef=coltypes, colnames=colnames, keycol=keycol
  101. )
  102. else:
  103. sql = "ALTER TABLE %s DROP COLUMN %s" % (table, column)
  104. try:
  105. grass.write_command(
  106. "db.execute", input="-", database=database, driver=driver, stdin=sql
  107. )
  108. except CalledModuleError:
  109. grass.fatal(_("Deleting column failed"))
  110. # write cmd history:
  111. grass.vector_history(map)
  112. if __name__ == "__main__":
  113. options, flags = grass.parser()
  114. main()