v.db.select(1)

✨ NAME ✨

v.db.select β€” bestie, this one prints vector map attributes. That's it, that's the whole job, and it does it beautifully. πŸ’–

Straight from the GRASS GIS User's Manual, section v.db.select(1). πŸ‘‘


πŸŽ€ KEYWORDS πŸŽ€

vector, attribute table, database, SQL, export β€” iykyk πŸ’…


πŸ¦‹ SYNOPSIS πŸ¦‹

v.db.select
v.db.select --help
v.db.select [-rcef] map=name  [layer=string]   [columns=name[,name,...]]
[where=sql_query]   [group=string]  format=name  [separator=character]
[vertical_separator=character]   [null_value=string]   [file=name]
[--overwrite]  [--help]  [--verbose]  [--quiet]  [--ui]

🌸 Flags 🌸

  • -r β€” instead of spitting out attributes, print the minimal region extent of the selected vector features. different vibe, same command ✨
  • -c β€” do not include column names in the output. no header, just vibes 🫢
  • -e β€” escape newline and backslash characters. lowkey essential, we'll get into it 😭
  • -f β€” exclude attributes that aren't linked to features
  • --overwrite β€” allow output files to overwrite existing files (chaotic but valid πŸ’€)
  • --help β€” print usage summary
  • --verbose β€” verbose module output (she's chatty, we love her)
  • --quiet β€” quiet module output
  • --ui β€” force launching the GUI dialog

🌈 Parameters 🌈

  • map=name [required] β€” name of vector map. or, plot twist, a data source for direct OGR access πŸ‘€
  • layer=string β€” layer number or name. here's the tea: vector features can have category values in different layers, and this number determines which layer to use. when you're using direct OGR access, this is the layer name. default: 1 ✨
  • columns=name[,name,...] β€” name of attribute column(s). plural! she's flexible πŸ’…
  • where=sql_query β€” WHERE conditions of an SQL statement, but without the where keyword. example: income < 1000 and population >= 10000
  • group=string β€” GROUP BY conditions of an SQL statement, also without the group by keyword
  • format=name [required] β€” output format
    • Options: plain, csv, json, vertical
    • Default: plain
    • plain: configurable plain text output
    • csv: CSV (Comma Separated Values)
    • json: JSON (JavaScript Object Notation)
    • vertical: plain text vertical output (instead of horizontal)
  • separator=character β€” field separator. special characters: pipe, comma, space, tab, newline
  • vertical_separator=character β€” output vertical record separator. special characters: pipe, comma, space, tab, newline
  • null_value=string β€” string representing the NULL value
  • file=name β€” name for output file. if it's omitted, or if it's -, output goes to stdout 🫢

πŸ’œ DESCRIPTION πŸ’œ

v.db.select prints the attributes of a vector map, pulled from one or several attribute table columns that you picked. main character energy, honestly. πŸ‘‘

πŸ’« Output formats πŸ’«

Four different formats, bestie β€” pick based on the situation using the format option: plain text, CSV, JSON, and vertical plain text. 🌈

πŸ“ Plain text πŸ“

Plain text is the default output, and it's the one most suitable for reading by humans. like, when you're chillin' in the command line, or grabbing specific values from the attribute table using the v.db.select GUI dialog. it's giving cozy. πŸŽ€

The individual fields (that's the attribute values) are separated by a pipe (|), and you can customize that with the separator option. The records (the rows) are separated by newlines. periodt.

Example with a pipe as a separator (the default):

cat|road_name|multilane|year|length
1|NC-50|no|2001|4825.369405
2|NC-50|no|2002|14392.589058
3|NC-98|no|2003|3212.981242
4|NC-50|no|2004|13391.907552

When escaping is enabled, these characters in the fields get escaped: backslash (\\), carriage return (\r), line feed (\n), tabulator (\t), form feed (\f), and backslash (\b). ✨

No quoting or escaping is performed by default, so if these characters show up in the output, they look exactly like the separators. πŸ’€

ngl, that's usually not a problem for humans just glancing at the output to get a general idea about a query result or attribute table content.

So consequently β€” and hear me out β€” this format is not recommended for computers, like, not for reading attribute data in Python scripts. it does work for further parsing in limited cases, specifically when the values don't contain separators, or when the separators are set to one of the escaped characters. iykyk 🫢

🧚 CSV 🧚

CSV (comma-separated values) has many variations, bestie, it's complicated. This module by default produces CSV with comma (,) as the field separator (delimiter). All text fields (based on the type) are quoted with double quotes. Double quotes inside fields are represented as two double quotes. Newline characters in the fields are present as-is in the output. Header is included by default, containing column names. slay. ✨

All full CSV parsers β€” like the ones in LibreOffice or Python β€” are able to parse this format when configured to the above specification. πŸ’…

Example with default settings:

cat,road_name,multilane,year,length
1,"NC-50","no",2001,4825.369405
2,"NC-50","no",2002,14392.589058
3,"NC-98","no",2003,3212.981242
4,"NC-50","no",2004,13391.907552

If you want, the separator can be customized and escaping can be enabled, with the same characters being escaped as for the plain text. Notably: newlines and tabs are escaped, double quotes are not, and the separator is not escaped either (unless it's a tab). However, the format is only guaranteed for the commonly used separators such as comma, semicolon, pipe, and tab. no cap.

Note that using a multi-character separator is allowed, but not recommended, since it's not generally supported by CSV readers. 🚩

CSV is the recommended format for further use in other analytical applications, especially with spreadsheet applications. For scripting, it's advantageous when you need tabular data (rather than key-value pairs). 🌸

⭐ JSON ⭐

JSON (JavaScript Object Notation) format is produced according to the specification, so it's readily readable by JSON parsers. The standard JSON escapes are performed (backslash, carriage return, line feed, tabulator, form feed, backslash, and double quote) for string values. Numbers in the database β€” like integers and doubles β€” are represented as numbers, while texts (TEXT, VARCHAR, etc.) and dates in the database are represented as strings in JSON. NULL values in the database are represented as JSON null. Indentation and newlines in the output are minimal and not guaranteed. πŸ’€

Records which are the result of the query are stored under key records, as an array (list) of objects (collections of key-value pairs). The keys for attributes are lowercase or uppercase depending on how the columns were defined in the database. πŸ‘‘

The JSON also contains information about columns stored under key info. Column names and types are under key columns. Each column has an SQL data type under sql_type in all caps. A boolean is_number specifies whether the value is a number, i.e., an integer or floating point number. The is_number value is added for convenience, and it's recommended to rely on the types derived from the JSON representation or the SQL types. The definition of is_number may change in the future. πŸ¦‹

Example with added indentation:

{
  "info": {
    "columns": [
      {
        "name": "road_name",
        "sql_type": "CHARACTER",
        "is_number": false
      },
      {
        "name": "year",
        "sql_type": "INTEGER",
        "is_number": true
      },
      {
        "name": "length",
        "sql_type": "DOUBLE PRECISION",
        "is_number": true
      }
    ]
  },
  "records": [
    {
      "road_name": "NC-50",
      "year": 2001,
      "length": 4825.369405
    },
    {
      "road_name": "NC-50",
      "year": 2001,
      "length": 14392.589058
    }
  ]
}

JSON is the recommended format for reading the data in Python, and for any uses and environments where convenient access to individual values is desired and a JSON parser is available. 🌈

πŸŽ€ Vertical plain text πŸŽ€

In the vertical plain text format, each value is on a single line and is preceded by the name of the attribute (column), separated by separator. The individual records can be separated by the vertical separator (the vertical_separator option). 🫢

Example with (horizontal) separator = and vertical separator newline:

cat=1
road_name=NC-50
multilane=no
year=2001
length=4825.369405
cat=2
road_name=NC-50
multilane=no
year=2002
length=14392.589058

Newline is automatically added after a vertical separator unless it is a newline, which allows for separating the records, e.g., by multiple dashes. The escaping (-e) should be enabled in case the output is meant for reading by a computer rather than just as a data overview for humans. Escaping will ensure that values with newlines will be contained to a single line. This format is for special uses in scripting β€” for example, in combination with the columns option set to one column only, plus escaping (-e) and the no column names flag (-c). It's also advantageous when you need to implement the parsing yourself. πŸ’…


πŸ’œ NOTES πŸ’œ

  • CSV and JSON were added in version 8.0 as new primary formats for further consumption by scripts and other applications. ✨
  • Escaping of plain and vertical formats was extended from just backslash and newlines to all escapes from JSON except for the double quote character. πŸŽ€

πŸ’– EXAMPLES πŸ’–

Every single one of these baddies is built on the North Carolina sample dataset, okay? So go grab that if you wanna play along. 🌈


πŸ¦‹ Select and show entire table

No filters, no drama, just the whole vibe:

v.db.select map=roadsmajor
cat|MAJORRDS_|ROAD_NAME|MULTILANE|PROPYEAR|OBJECTID|SHAPE_LEN
1|1|NC-50|no|0|1|4825.369405
2|2|NC-50|no|0|2|14392.589058
3|3|NC-98|no|0|3|3212.981242
4|4|NC-50|no|0|4|13391.907552
...

The ... at the end is the table being like "bestie there's more, I'm just not gonna say it all". 😭


🌸 Select and show single column from table

Note: you can flex multiple columns too, just comma-separate them like a little list. slay.
v.db.select map=roadsmajor column=ROAD_NAME
NC-50
NC-50
NC-98
NC-50
NC-98
...

One column, zero clutter, iconic. ✨


You want the region extent? Say less. Add -r and it gives you the n, s, w, e tea:

v.db.select -r map=roadsmajor where="ROAD_NAME = ’NC-98’"
n=248425.389891
s=245640.640081
w=635906.517653
e=661979.801880

🫢 Select empty vector features (no data entries)

Empty fields are a whole mood, and IS NULL is how you catch them:

v.db.select geonames_wake where="ALTERNATEN IS NULL"
cat|GEONAMEID|NAME|ASCIINAME|ALTERNATEN|FEATURECLA|FEATURECOD|...
8|4498303|West Raleigh|West Raleigh||P|PPL|US||NC|338759|123|...
14|4459467|Cary|Cary||P|PPL|US||NC|103945|146|152|America/Iqaluit|...
31|4452808|Apex|Apex||P|PPL|US||NC|30873|167|134|America/Iqaluit|...
...

See those little gaps between the | pipes? That's the emptiness. πŸ™ˆ


🧚 Select not empty vector features (no data entries)

And flipping it β€” IS NOT NULL β€” gives you only the rows that actually showed up with something to say:

v.db.select geonames_wake where="ALTERNATEN IS NOT NULL"
cat|GEONAMEID|NAME|ASCIINAME|ALTERNATEN|FEATURECLA|FEATURECOD|...
9|4487042|Raleigh|Raleigh|Raleigh,...
31299|4487056|Raleigh-Durham Airport|Raleigh-Durham Airport|...
...

πŸ’… Select features with distinct road names

Here's where group comes in and eats. 🍽️

v.db.select map=roadsmajor columns=ROAD_NAME group=ROAD_NAME
ROAD_NAME
I-40
I-440
I-540
NC-231
NC-39
NC-42
...

It is also possible to combine with where option β€” so like, you can gatekeep and group at the same time:

v.db.select map=roadsmajor columns=ROAD_NAME,MULTILANE group=ROAD_NAME where=’ROAD_NAME is not null’
ROAD_NAME|MULTILANE
I-40|yes
I-440|yes
I-540|yes
NC-231|no
NC-39|no
NC-42|no
NC-50|no
NC-54|no
NC-55|no
NC-96|no
NC-97|no
NC-98|no
US-1|
US-401|no
US-64|yes
US-70|yes

It can also use more columns in group option β€” more columns, more chaos, more slay:

v.db.select map=roadsmajor columns=ROAD_NAME,MULTILANE group=ROAD_NAME,MULTILANE where=’ROAD_NAME is not null’
ROAD_NAME|MULTILANE
I-40|yes
I-440|yes
I-540|yes
NC-231|no
NC-39|no
NC-42|no
NC-50|no
NC-54|no
NC-55|no
NC-96|no
NC-97|no
NC-98|no
US-1|
US-1|yes
US-401|no
US-401|yes
US-64|yes
US-70|yes

Not US-1 and US-401 showing up twice now because they got both an empty MULTILANE and a filled one β€” different groups, different rows, no cap. πŸ‘‘


⭐ Read results in Python

Okay this one is genuinely so useful, the json package in the standard Python library can load a JSON string that you got as output from the v.db.select module through the read_command function:

import json
import grass.script as gs

text = gs.read_command("v.db.select", map="roadsmajor", format="json")
data = json.loads(text)
for row in data["records"]:
    print(row["ROAD_NAME"])

Loops through every record and prints ROAD_NAME. Main character energy, fr fr. πŸ’œ


✨ SEE ALSO ✨

  • db.select
  • GRASS SQL interface

Go read those next, bestie, they're the supporting cast and they serve. 🫢


🌈 AUTHORS 🌈

Give it up for the people who built this. πŸ‘

  • Radim Blazek, ITC-Irst, Trento, Italy
  • Minimal region extent added by Martin Landa, FBK-irst (formerly ITC-irst), Trento, Italy
  • Group option added by Luca Delucchi, Fondazione Edmund Mach, Trento, Italy
  • Huidae Cho (JSON output, escaping and features-only flags)
  • Vaclav Petras (true CSV output, format option and documentation)

πŸ‘‘ SOURCE CODE πŸ‘‘

Available at: v.db.select source code (history)

Accessed: Saturday Jan 17 05:41:20 2026

Main index | Vector index | Topics index | Keywords index | Graphical index | Full index


Β© 2003-2025 GRASS Development Team, GRASS GIS 8.4.2 Reference Manual

Okay that's the whole page, bestie!! πŸ’– This was v.db.select(1) from GRASS 8.4.2, and yeah the manual was last accessed Saturday Jan 17 05:41:20 2026 β€” so go forth, select some columns, group some rows, and stay iconic. πŸ’…βœ¨πŸ¦‹

πŸ“¦ where this page comes from