123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- #!/usr/bin/env python3
- ############################################################################
- #
- # MODULE: v.db.dropcolumn
- # AUTHOR(S): Markus Neteler
- # Converted to Python by Glynn Clements
- # PURPOSE: interface to db.execute to drop a column from the
- # attribute table connected to a given vector map
- # - Based on v.db.addcolumn
- # - with special trick for SQLite
- # COPYRIGHT: (C) 2007 by the GRASS Development Team
- #
- # This program is free software under the GNU General Public
- # License (>=v2). Read the file COPYING that comes with GRASS
- # for details.
- #
- #############################################################################
- # %module
- # % description: Drops a column from the attribute table connected to a given vector map.
- # % keyword: vector
- # % keyword: attribute table
- # % keyword: database
- # %end
- # %option G_OPT_V_MAP
- # % key: map
- # %end
- # %option G_OPT_V_FIELD
- # %end
- # %option G_OPT_DB_COLUMNS
- # % description: Name of attribute column(s) to drop
- # % required: yes
- # %end
- import string
- import grass.script as grass
- from grass.exceptions import CalledModuleError
- def main():
- map = options["map"]
- layer = options["layer"]
- columns = options["columns"].split(",")
- mapset = grass.gisenv()["MAPSET"]
- # does map exist in CURRENT mapset?
- if not grass.find_file(map, element="vector", mapset=mapset)["file"]:
- grass.fatal(_("Vector map <%s> not found in current mapset") % map)
- f = grass.vector_layer_db(map, layer)
- table = f["table"]
- keycol = f["key"]
- database = f["database"]
- driver = f["driver"]
- if not table:
- grass.fatal(
- _(
- "There is no table connected to the input vector map. "
- "Unable to delete any column. Exiting."
- )
- )
- if keycol in columns:
- grass.fatal(
- _(
- "Unable to delete <%s> column as it is needed to keep table <%s> "
- "connected to the input vector map <%s>"
- )
- % (keycol, table, map)
- )
- for column in columns:
- if column not in grass.vector_columns(map, layer):
- grass.warning(
- _("Column <%s> not found in table <%s>. Skipped") % (column, table)
- )
- continue
- if driver == "sqlite":
- # echo "Using special trick for SQLite"
- # http://www.sqlite.org/faq.html#q11
- colnames = []
- coltypes = []
- for f in grass.db_describe(table, database=database, driver=driver)["cols"]:
- if f[0] == column:
- continue
- colnames.append(f[0])
- # see db_sqltype_name() for type names
- if f[1] == "CHARACTER":
- # preserve field length for sql type "CHARACTER"
- coltypes.append("%s %s(%s)" % (f[0], f[1], f[2]))
- else:
- coltypes.append("%s %s" % (f[0], f[1]))
- colnames = ", ".join(colnames)
- coltypes = ", ".join(coltypes)
- cmds = [
- "BEGIN TRANSACTION",
- "CREATE TEMPORARY TABLE ${table}_backup (${coldef})",
- "INSERT INTO ${table}_backup SELECT ${colnames} FROM ${table}",
- "DROP TABLE ${table}",
- "CREATE TABLE ${table}(${coldef})",
- "INSERT INTO ${table} SELECT ${colnames} FROM ${table}_backup",
- "CREATE UNIQUE INDEX ${table}_cat ON ${table} (${keycol} )",
- "DROP TABLE ${table}_backup",
- "COMMIT",
- ]
- tmpl = string.Template(";\n".join(cmds))
- sql = tmpl.substitute(
- table=table, coldef=coltypes, colnames=colnames, keycol=keycol
- )
- else:
- sql = "ALTER TABLE %s DROP COLUMN %s" % (table, column)
- try:
- grass.write_command(
- "db.execute", input="-", database=database, driver=driver, stdin=sql
- )
- except CalledModuleError:
- grass.fatal(_("Deleting column failed"))
- # write cmd history:
- grass.vector_history(map)
- if __name__ == "__main__":
- options, flags = grass.parser()
- main()
|