db.py 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. """@package grass.script.db
  2. @brief GRASS Python scripting module (database functions)
  3. Database related functions to be used in Python scripts.
  4. Usage:
  5. ::
  6. from grass.script import db as grass
  7. grass.db_describe(table)
  8. ...
  9. (C) 2008-2009, 2012 by the GRASS Development Team
  10. This program is free software under the GNU General Public
  11. License (>=v2). Read the file COPYING that comes with GRASS
  12. for details.
  13. .. sectionauthor:: Glynn Clements
  14. .. sectionauthor:: Martin Landa <landa.martin gmail.com>
  15. """
  16. from core import *
  17. from utils import try_remove
  18. def db_describe(table, **args):
  19. """Return the list of columns for a database table
  20. (interface to `db.describe -c'). Example:
  21. >>> run_command('g.copy', vect='firestations,myfirestations')
  22. 0
  23. >>> db_describe('myfirestations') # doctest: +ELLIPSIS
  24. {'nrows': 71, 'cols': [['cat', 'INTEGER', '20'], ... 'ncols': 22}
  25. >>> run_command('g.remove', vect='myfirestations')
  26. 0
  27. :param str table: table name
  28. :param list args:
  29. :return: parsed module output
  30. """
  31. s = read_command('db.describe', flags='c', table=table, **args)
  32. if not s:
  33. fatal(_("Unable to describe table <%s>") % table)
  34. cols = []
  35. result = {}
  36. for l in s.splitlines():
  37. f = l.split(':')
  38. key = f[0]
  39. f[1] = f[1].lstrip(' ')
  40. if key.startswith('Column '):
  41. n = int(key.split(' ')[1])
  42. cols.insert(n, f[1:])
  43. elif key in ['ncols', 'nrows']:
  44. result[key] = int(f[1])
  45. else:
  46. result[key] = f[1:]
  47. result['cols'] = cols
  48. return result
  49. def db_table_exist(table, **args):
  50. """Check if table exists.
  51. If no driver or database are given, then default settings is used
  52. (check db_connection()).
  53. >>> run_command('g.copy', vect='firestations,myfirestations')
  54. 0
  55. >>> db_table_exist('myfirestations')
  56. True
  57. >>> run_command('g.remove', vect='myfirestations')
  58. 0
  59. :param str table: table name
  60. :param args:
  61. :return: True for success, False otherwise
  62. """
  63. nuldev = file(os.devnull, 'w+')
  64. ret = run_command('db.describe', flags='c', table=table,
  65. stdout=nuldev, stderr=nuldev, **args)
  66. nuldev.close()
  67. if ret == 0:
  68. return True
  69. return False
  70. def db_connection():
  71. """Return the current database connection parameters
  72. (interface to `db.connect -g'). Example:
  73. >>> db_connection()
  74. {'group': '', 'schema': '', 'driver': 'sqlite', 'database': '$GISDBASE/$LOCATION_NAME/$MAPSET/sqlite/sqlite.db'}
  75. :return: parsed output of db.connect
  76. """
  77. return parse_command('db.connect', flags='g')
  78. def db_select(sql=None, filename=None, table=None, **args):
  79. """Perform SQL select statement
  80. Note: one of <em>sql</em>, <em>filename</em>, or <em>table</em>
  81. arguments must be provided.
  82. Examples:
  83. >>> run_command('g.copy', vect='firestations,myfirestations')
  84. 0
  85. >>> db_select(sql = 'SELECT cat,CITY FROM myfirestations WHERE cat < 4')
  86. (('1', 'Morrisville'), ('2', 'Morrisville'), ('3', 'Apex'))
  87. Simplyfied usage (it performs <tt>SELECT * FROM myfirestations</tt>.)
  88. >>> db_select(table = 'myfirestations') # doctest: +ELLIPSIS
  89. (('1', '24', 'Morrisville #3', ... 'HS2A', '1.37'))
  90. >>> run_command('g.remove', vect='myfirestations')
  91. 0
  92. :param str sql: SQL statement to perform (or None)
  93. :param str filename: name of file with SQL statements (or None)
  94. :param str table: name of table to query (or None)
  95. :param str args: see \gmod{db.select} arguments
  96. """
  97. fname = tempfile(create=False)
  98. if sql:
  99. args['sql'] = sql
  100. elif filename:
  101. args['input'] = filename
  102. elif table:
  103. args['table'] = table
  104. else:
  105. fatal(_("Programmer error: '%(sql)s', '%(filename)s', or '%(table)s' must be provided") %
  106. {'sql': 'sql', 'filename': 'filename', 'table': 'table'} )
  107. if 'sep' not in args:
  108. args['sep'] = '|'
  109. ret = run_command('db.select', quiet=True, flags='c',
  110. output=fname, **args)
  111. if ret != 0:
  112. fatal(_("Fetching data failed"))
  113. ofile = open(fname)
  114. result = map(lambda x: tuple(x.rstrip(os.linesep).split(args['sep'])),
  115. ofile.readlines())
  116. ofile.close()
  117. try_remove(fname)
  118. return tuple(result)
  119. def db_table_in_vector(table):
  120. """Return the name of vector connected to the table.
  121. It returns None if no vectors are connected to the table.
  122. >>> run_command('g.copy', vect='firestations,myfirestations')
  123. 0
  124. >>> db_table_in_vector('myfirestations')
  125. ['myfirestations@user1']
  126. >>> db_table_in_vector('mfirestations')
  127. >>> run_command('g.remove', vect='myfirestations')
  128. 0
  129. :param str table: name of table to query
  130. """
  131. from vector import vector_db
  132. nuldev = file(os.devnull, 'w')
  133. used = []
  134. vects = list_strings('vect')
  135. for vect in vects:
  136. for f in vector_db(vect, stderr=nuldev).itervalues():
  137. if not f:
  138. continue
  139. if f['table'] == table:
  140. used.append(vect)
  141. break
  142. if len(used) > 0:
  143. return used
  144. else:
  145. return None