[GRASS-user] v.db.join script
Micha Silver
micha at arava.co.il
Fri Oct 15 08:08:24 EDT 2010
Hi Jon:
So we're pretty clear that this problem creeps up only on PostgreSQL and
MySQL based vector layers. I checked in the documentation and both
databases will create a *one* char wide column when the CHARACTER type
is used without any size. Sqlite uses their "dynamic typing " so any
CHAR column can be any size and the bug gets "hidden"...
Here's a new v.db.join script that seems to overcome the width problem.
I tested *only* on a Postgresql based vector. It creates the full width
columns like in the original table. Would you mind testing on MySQL? To
use this scrpt, you'll have to drop it into your GRASS scripts directory
(probably /usr/lib/grass64/scripts ) and make sure it's executable. Then
run it as v.db.join2.
Additional note: If you're already using a spatial database, and you
have external data tables to join, wouldn't the best workflow be to
throw your new attributes into the database, and create a VIEW right in
MySQL??
Regards,
Micha
On 10/12/2010 12:01 PM, Jon Eiriksson wrote:
>
> Hi,
>
> I have a truncation problem with v.db.join. This has been raised before -
>
>
> ([GRASS-user] Re: grass v.db.join
>
> Gary Nobles
> Fri, 12 Mar 2010 11:11:26 -0800)
>
> - but I have not seen a solution. I have tried my own data, the
> spearfish60 example data, and the example in Neteler and Mitasova's book.
> The new data columns are apparently defined as 1 character long, and the
> data become truncated accordingly, much against my intention. I use
> mysql.
>
> Can anyone point out a solution? I copy a session with the spearfish60
> data below.
>
> Jon
>
> GRASS 6.4.0 (spearfish60):~ > g.copy vect=soils,mysoils
> Copy vector <soils at PERMANENT> to current mapset as <mysoils>
> GRASS 6.4.0 (spearfish60):~ > db.select mysoils
> cat|label
> 1|Aab
> 2|Ba
> 3|Bb
> 4|BcB
> 5|BcC
> 6|BeE
> .
> .
> .
> GRASS 6.4.0 (spearfish60):~ > db.in.ogr soils_legend.csv out=soils_legend
> Imported table <soils_legend> with 55 rows
> GRASS 6.4.0 (spearfish60):~ > db.select soils_legend
> id|shortname|longname
> 0|no data|no data
> 1|AaB|Alice fine sandy loam, 0 to 6
> 2|Ba|Barnum silt loam
> 3|Bb|Barnum silt loam, channeled
> 4|BcB|Boneek silt loam, 2 to 6
> 5|BcC|Boneek silt loam, 6 to 9
> 6|BeE|Butche stony loam, 6 to 50
> .
> .
> .
> GRASS 6.4.0 (spearfish60):~ > v.db.join mysoils col=label
> otable=soils_legend ocol=shortname
> GRASS 6.4.0 (spearfish60):~ > v.db.select mysoils
> cat|label|id|shortname|longname
> 1|Aab|1|A|A
> 2|Ba|2|B|B
> 3|Bb|3|B|B
> 4|BcB|4|B|B
> 5|BcC|5|B|B
> 6|BeE|6|B|B
> .
> .
> .
> GRASS 6.4.0 (spearfish60):~ > db.describe -c mysoils
> ncols: 5
> nrows: 54
> Column 1: cat:INTEGER:11
> Column 2: label:CHARACTER:13
> Column 3: id:CHARACTER:1
> Column 4: shortname:CHARACTER:1
> Column 5: longname:CHARACTER:1
> GRASS 6.4.0 (spearfish60):~ > db.describe -c soils_legend
> ncols: 3
> nrows: 55
> Column 1: id:CHARACTER:255
> Column 2: shortname:CHARACTER:255
> Column 3: longname:CHARACTER:255
> GRASS 6.4.0 (spearfish60):~ >
> ==================================================
>
>
> -------------------------------------------------------------------
> Jon Eiriksson, Research Professor,
> Earth Science Institute, University of Iceland,
> Askja, Sturlugata 7,
> IS-101 Reykjavik, Iceland.
>
> Tel +354 525 44 75
> Fax +354 525 44 99
> Email jeir at hi.is
> Web http://www.raunvis.hi.is/~jeir/
> -------------------------------------------------------------------
>
>
>
>
> _______________________________________________
> grass-user mailing list
> grass-user at lists.osgeo.org
> http://lists.osgeo.org/mailman/listinfo/grass-user
>
> This mail was received via Mail-SeCure System.
>
>
--
Micha Silver
Arava Development Co. +972-52-3665918
http://www.surfaces.co.il
-------------- next part --------------
#!/bin/sh
############################################################################
#
# MODULE: v.db.join
# AUTHOR(S): Markus Neteler
# PURPOSE: Join a table to a map table
# COPYRIGHT: (C) 2007-2008 by Markus Neteler and 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: Allows to join a table to a vector map table.
#% keywords: vector, database, attribute table
#%End
#%option
#% key: map
#% type: string
#% key_desc : name
#% gisprompt: old,vector,vector
#% description: Vector map to which to join other table
#% required : yes
#%end
#%option
#% key: layer
#% type: integer
#% description: Layer where to join
#% answer: 1
#% required : no
#% gisprompt: old_layer,layer,layer
#%end
#%option
#% key: column
#% type: string
#% description: Join column in map table
#% required : yes
#% gisprompt: old_dbcolumn,dbcolumn,dbcolumn
#%end
#%option
#% key: otable
#% type: string
#% description: Other table name
#% required : yes
#% gisprompt: old_dbtable,dbtable,dbtable
#%end
#%option
#% key: ocolumn
#% type: string
#% description: Join column in other table
#% required : yes
#% gisprompt: old_dbcolumn,dbcolumn,dbcolumn
#%end
if [ -z "$GISBASE" ] ; then
echo "You must be in GRASS GIS to run this program." >&2
exit 1
fi
# save command line
if [ "$1" != "@ARGS_PARSED@" ] ; then
CMDLINE="`basename $0`"
for arg in "$@" ; do
CMDLINE="$CMDLINE \"$arg\""
done
export CMDLINE
exec g.parser "$0" "$@"
fi
PROG=`basename $0`
driver=`v.db.connect -g map="$GIS_OPT_MAP" fs=";" | grep "^$GIS_OPT_LAYER" | cut -d';' -f5`
database=`v.db.connect -g map="$GIS_OPT_MAP" fs=";" | grep "^$GIS_OPT_LAYER" | cut -d';' -f4`
if [ "$driver" = "dbf" ] ; then
g.message -e "JOIN is not supported for tables stored in DBF format."
exit 1
fi
maptable=`v.db.connect -g map="$GIS_OPT_MAP" fs=";" | grep "^$GIS_OPT_LAYER" | cut -d';' -f2`
if [ -z "$maptable" ] ; then
g.message 'There is no table connected to this map! Cannot join any column.'
### cleanup
exit 1
fi
v.info --quiet -c "$GIS_OPT_MAP" layer="$GIS_OPT_LAYER" | \
cut -d'|' -f1,2 | grep "|${GIS_OPT_COLUMN}$" 2>&1 >/dev/null
if [ $? -ne 0 ] ; then
g.message -e "Column <$GIS_OPT_COLUMN> not found in table <$GIS_OPT_MAP> at layer $GIS_OPT_LAYER"
exit 1
fi
# we use map DBMI settings
COLLIST=`db.describe -c driver="$driver" database="$database" table="$GIS_OPT_OTABLE" | grep '^Column ' | cut -d':' -f2`
# heck, types may have white space
COLTYPES=`db.describe -c driver="$driver" database="$database" table="$GIS_OPT_OTABLE" | grep '^Column ' | cut -d':' -f3 | tr -s ' ' '_'`
###########################
#### Addition by Micha ####
# Also grab column widths
COLWIDTHS=`db.describe -c driver="$driver" database="$database" table="$GIS_OPT_OTABLE" | grep '^Column ' | cut -d':' -f4`
#### End ####
###########################
i=1
for col in $COLLIST ; do
###########################
#### Addition by Micha ###
# if the column is a CHAR type, use the COLWIDTH value to create a VARCHAR column
COLTYPE=`echo $COLTYPES | cut -d' ' -f$i | tr -s '_' ' '`
COLWIDTH=`echo $COLWIDTHS | cut -d' ' -f$i`
if [ "$COLTYPE" = "CHARACTER" ]; then
v.db.addcol "$GIS_OPT_MAP" layer="$GIS_OPT_LAYER" col="$col VARCHAR($COLWIDTH)"
else
v.db.addcol "$GIS_OPT_MAP" layer="$GIS_OPT_LAYER" col="$col $COLTYPE"
fi
# v.db.addcol "$GIS_OPT_MAP" layer="$GIS_OPT_LAYER" col="$col `echo $COLTYPES | cut -d' ' -f$i | tr -s '_' ' '`"
#### End ####
###########################
if [ $? -ne 0 ] ; then
g.message -e "Cannot continue."
exit 1
fi
echo "UPDATE $maptable SET $col=(SELECT $col
FROM $GIS_OPT_OTABLE WHERE $GIS_OPT_OTABLE.$GIS_OPT_OCOLUMN=$maptable.$GIS_OPT_COLUMN);" | db.execute database="${database}" driver=${driver}
i=`expr $i + 1`
done
# write cmd history:
v.support "${GIS_OPT_MAP}" cmdhist="${CMDLINE}"
exit 0
More information about the grass-user
mailing list