{{full_name}}{{geo_level}}
' ) @@ -1199,7 +1205,7 @@ function Comparison(options) { displayKey: 'full_name', source: comparison.geoSelectEngine.ttAdapter(), templates: { - header: '{{full_name}}{{sumlev_name}}
' ) @@ -1230,7 +1236,7 @@ function Comparison(options) { if (!!comparison.primaryGeoID && !_.isEmpty(sumlevMap[comparison.thisSumlev].ancestors)) { var parentGeoAPI = comparison.rootGeoAPI + comparison.primaryGeoID + '/parents', parentOptionsContainer = comparison.aside.append('div') - .attr('class', 'aside-block hidden-ci') + .attr('class', 'aside-block hidden') .attr('id', 'comparison-parents'); $.getJSON(parentGeoAPI) @@ -1575,6 +1581,10 @@ function Comparison(options) { } comparison.getStatType = function() { + if (comparison.table.stat_type == 'percentage') { + return 'percentage'; + } + var title = comparison.table.title.toLowerCase(); if (title.indexOf('dollars') !== -1 && title.indexOf('percent') == -1) { @@ -1702,7 +1712,7 @@ function Comparison(options) { ga('send', 'event', category, action, label); } } - + comparison.addNumbertoggles = function(redrawFunction) { d3.select('#number-toggles').remove(); var toggleText = (comparison.valueType == 'estimate') ? 'Switch to percentages' : 'Switch to totals', @@ -1723,9 +1733,8 @@ function Comparison(options) { comparison.loadMapData = function(cb) { GeometryLoader.loadGeometryForComparison(comparison, cb); } - + // ready, set, go comparison.init(options); return comparison; } - diff --git a/janaganana/static/js/embed.chart.frame.js b/janaganana/static/js/embed.chart.frame.js index 020e35b..a17ae57 100644 --- a/janaganana/static/js/embed.chart.frame.js +++ b/janaganana/static/js/embed.chart.frame.js @@ -23,11 +23,13 @@ function makeEmbedFrame() { embedFrame.params.chartDataID = embedFrame.params.chartDataID.split('-'); embedFrame.params.chartDataYearDir = (!!embedFrame.params.dataYear) ? embedFrame.params.dataYear+'/' : ''; embedFrame.dataSource = '/profiles/'+embedFrame.params.geoID+'.json'; + if (embedFrame.params.geoVersion) embedFrame.dataSource += '?geo_version=' + embedFrame.params.geoVersion; + // avoid css media-query caching issues with multiple embeds on same page - $('#chart-styles').attr('href','css/charts.css?'+embedFrame.parentContainerID) + $('#chart-styles').attr('href','css/charts.css?'+embedFrame.parentContainerID); // allow embedders to inject their own stylesheet - if (embedFrame.params['stylesheet']) { + if (embedFrame.params.stylesheet) { $('').attr('href', embedFrame.params.stylesheet).appendTo($('head')); } @@ -109,7 +111,7 @@ function makeEmbedFrame() { .classed('title', true) .attr('href', SITE_URL + '/profiles/' + embedFrame.params.geoID + '/') .attr('target', '_blank') - .html(' ' + SITE_NAME); + .html(' ' + SITE_NAME); } embedFrame.addChartListeners = function() { diff --git a/janaganana/static/js/maps_static.js b/janaganana/static/js/maps_static.js index 59a103f..93c05ab 100644 --- a/janaganana/static/js/maps_static.js +++ b/janaganana/static/js/maps_static.js @@ -20,7 +20,7 @@ function StaticGeometryLoader(geometry_urls) { * callback with an object mapping each geo-id to a GeoJSON object. */ this.loadGeometryForComparison = function(comparison, success) { - this.loadGeometryForGeoIds(comparison.dataGeoIDs, success); + this.loadGeometryForGeoIds(comparison.dataGeoIDs, comparison.geoVersion, success); }; /** @@ -28,7 +28,7 @@ function StaticGeometryLoader(geometry_urls) { * and calls the +success+ callback with an object mapping * each geo-id to a GeoJSON object. */ - this.loadGeometryForGeoIds = function(geo_ids, success) { + this.loadGeometryForGeoIds = function(geo_ids, geo_version, success) { var by_level = {}; _.each(geo_ids, function(geo_id) { @@ -42,12 +42,12 @@ function StaticGeometryLoader(geometry_urls) { }); // load the levels we need - self.loadLevels(_.keys(by_level), function() { + self.loadLevels(_.keys(by_level), geo_version, function() { var features = {}; _.each(by_level, function(geo_ids, level) { _.each(geo_ids, function(geo_id) { - features[geo_id] = self.geometry[level][geo_id]; + features[geo_id] = self.geometry[geo_version][level][geo_id]; }); }); @@ -55,16 +55,16 @@ function StaticGeometryLoader(geometry_urls) { }); }; - this.loadGeometryForLevel = function(level, success) { - self.loadLevels([level], function() { - success({features: _.values(self.geometry[level])}); + this.loadGeometryForLevel = function(level, geo_version, success) { + self.loadLevels([level], geo_version, function() { + success({features: _.values(self.geometry[geo_version][level])}); }); }; /** * Load the geometry data for +levels+ and then call +success+. */ - this.loadLevels = function(levels, success) { + this.loadLevels = function(levels, geo_version, success) { var counter = levels.length; function loaded(level) { @@ -75,17 +75,18 @@ function StaticGeometryLoader(geometry_urls) { } _.each(levels, function(level) { - if (self.geometry[level]) { + if (self.geometry[geo_version] && self.geometry[geo_version][level]) { // already have it loaded(level); } else { // load it remotely - d3.json(self.geometry_urls[level], function(error, json) { + d3.json(self.geometry_urls[geo_version][level], function(error, json) { var features; if (error) return console.warn(error); if (json) { - self.geometry[level] = {}; + if (!self.geometry[geo_version]) self.geometry[geo_version] = {}; + self.geometry[geo_version][level] = {}; if (json.type == 'Topology') { // topojson -> geojson @@ -100,7 +101,7 @@ function StaticGeometryLoader(geometry_urls) { // stash them _.each(features, function(feature) { - self.geometry[level][feature.properties.geoid] = feature; + self.geometry[geo_version][level][feature.properties.geoid] = feature; }); } diff --git a/janaganana/static/js/profile_map.js b/janaganana/static/js/profile_map.js index bbb2c3a..3ad6e34 100644 --- a/janaganana/static/js/profile_map.js +++ b/janaganana/static/js/profile_map.js @@ -31,7 +31,7 @@ var ProfileMaps = function() { this.drawAllFeatures(); }; - this.drawMapForHomepage = function(geo_level, centre, zoom) { + this.drawMapForHomepage = function(geo_level, geo_version, centre, zoom) { // draw a homepage map, but only for big displays if (browserWidth < 768 || $('#slippy-map').length === 0) return; @@ -42,7 +42,7 @@ var ProfileMaps = function() { self.map.setView(centre, zoom); } - GeometryLoader.loadGeometryForLevel(geo_level, function(features) { + GeometryLoader.loadGeometryForLevel(geo_level, geo_version, function(features) { var layer = self.drawFeatures(features); if (!centre) { self.map.fitBounds(layer.getBounds()); @@ -82,14 +82,12 @@ var ProfileMaps = function() { this.drawAllFeatures = function() { var geo_level = this.geo.this.geo_level; var geo_code = this.geo.this.geo_code; + var geo_version = this.geo.this.version; var osm_area_id = this.geo.this.osm_area_id; var child_level = this.geo.this.child_level; - if (geo_code == 550 || geo_code == 552) - console.log("level: ", geo_level, "code: ", geo_code); - // load all map shapes for this level - GeometryLoader.loadGeometryForLevel(geo_level, function(features) { + GeometryLoader.loadGeometryForLevel(geo_level, geo_version, function(features) { // split into this geo, and everything else var groups = _.partition(features.features, function(f) { return f.properties.code == geo_code; @@ -108,7 +106,7 @@ var ProfileMaps = function() { // load shapes at the child level, if any if (child_level) { - GeometryLoader.loadGeometryForLevel(child_level, function(features) { + GeometryLoader.loadGeometryForLevel(child_level, geo_version, function(features) { self.drawFeatures(features); }); } @@ -123,9 +121,6 @@ var ProfileMaps = function() { if (browserWidth > 768) { var z; - - /* disable zoom calculation till we identify the root cause */ - /* for(z = 16; z > 2; z--) { var swPix = this.map.project(objBounds.getSouthWest(), z), nePix = this.map.project(objBounds.getNorthEast(), z), @@ -135,17 +130,7 @@ var ProfileMaps = function() { break; } } - */ - - if (feature.properties.level === "country") - z = 4; - else if (feature.properties.level === "state") - z = 6; - else if (feature.properties.level === "district") - z = 9; - else - z = 4; - + this.map.setView(layer.getBounds().getCenter(), z); this.map.panBy([-270, 0], {animate: false}); } else { @@ -154,14 +139,11 @@ var ProfileMaps = function() { }; this.drawFeatures = function(features) { - function capitalize(str) { - return str.replace(/\w\S*/g, function(txt){return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();}); - } // draw all others return L.geoJson(features, { style: this.layerStyle, onEachFeature: function(feature, layer) { - layer.bindLabel(capitalize(feature.properties.name), {direction: 'auto'}); + layer.bindLabel(feature.properties.name, {direction: 'auto'}); layer.on('mouseover', function() { layer.setStyle(self.hoverStyle); diff --git a/janaganana/static/js/table.detail.js b/janaganana/static/js/table.detail.js index 0859609..cf92cec 100644 --- a/janaganana/static/js/table.detail.js +++ b/janaganana/static/js/table.detail.js @@ -203,7 +203,7 @@ function Table(options) { displayKey: 'full_name', source: table.placeSelectEngine.ttAdapter(), templates: { - header: '{{full_name}}{{sumlev_name}}
' ) @@ -247,7 +247,7 @@ function Table(options) { displayKey: 'full_name', source: table.placeSelectEngine.ttAdapter(), templates: { - header: '{{full_name}}{{sumlev_name}}
' ) @@ -295,4 +295,3 @@ function Table(options) { table.init(options); return table; } - diff --git a/janaganana/tables.py b/janaganana/tables.py index 063daa1..8baa8a0 100644 --- a/janaganana/tables.py +++ b/janaganana/tables.py @@ -3,18 +3,18 @@ # Define our tables so the data API can discover them. # Household tables -FieldTable(['rural population'], universe='Population', table_per_level=False) +FieldTable(['rural population'], universe='Population') -FieldTable(['area', 'sex'], universe='Population', table_per_level=False) +FieldTable(['area', 'sex'], universe='Population') -FieldTable(['area', 'sex', 'literacy'], universe='Population', table_per_level=False) +FieldTable(['area', 'sex', 'literacy'], universe='Population') -FieldTable(['religion', 'area', 'sex'], universe='Religion', table_per_level=False) +FieldTable(['religion', 'area', 'sex'], universe='Religion') -FieldTable(['age', 'area', 'sex'], universe='Age', table_per_level=False) +FieldTable(['age', 'area', 'sex'], universe='Age') -FieldTable(['education', 'area', 'sex'], universe='Education', table_per_level=False) +FieldTable(['education', 'area', 'sex'], universe='Education') -FieldTable(['maritalstatus', 'area', 'sex'], universe='Relation', table_per_level=False) +FieldTable(['maritalstatus', 'area', 'sex'], universe='Relation') -FieldTable(['workers', 'area', 'workerssex'], universe='Workers', table_per_level=False) +FieldTable(['workers', 'area', 'workerssex'], universe='Workers') diff --git a/janaganana/templates/homepage.html b/janaganana/templates/homepage.html index 227ec3a..5fcbab0 100644 --- a/janaganana/templates/homepage.html +++ b/janaganana/templates/homepage.html @@ -1,4 +1,4 @@ -{% extends '_base.html' %}{% load humanize partition staticfiles %} +{% extends '_base.html' %}{% load humanize partition staticfiles jsonify %} {% block head_title %}{{ block.super }}: Making Census Data Easy to Use{% endblock %} {% block head_meta_description %}{{ WAZIMAP.name }} provides useful facts about places in {{ root_geo.name }}. Compare places using tables and maps, download data, and embed charts on your site!{% endblock %} @@ -158,7 +158,7 @@ var maps = new ProfileMaps(); var centre = {% if WAZIMAP.map_centre %}{{ WAZIMAP.map_centre }}{% else %}null{% endif %}; var zoom = {% if WAZIMAP.map_zoom %}{{ WAZIMAP.map_zoom }}{% else %}null{% endif %}; -maps.drawMapForHomepage('{{ geo_data.first_child_level }}', centre, zoom); +maps.drawMapForHomepage({{ geo_data.first_child_level|jsonify|safe }}, {{ WAZIMAP.default_geo_version|jsonify|safe }}, centre, zoom); {% endblock %} diff --git a/janaganana/wsgi.py b/janaganana/wsgi.py new file mode 100644 index 0000000..87e3430 --- /dev/null +++ b/janaganana/wsgi.py @@ -0,0 +1,7 @@ +import os + +from django.core.wsgi import get_wsgi_application + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "janaganana.settings") + +application = get_wsgi_application() diff --git a/requirements.txt b/requirements.txt index 0001d92..31ea61c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,54 +1,11 @@ -awsebcli==3.8.3 -blessed==1.9.5 -boto==2.43.0 -botocore==1.4.71 -cement==2.8.2 -colorama==0.3.7 -Cython==0.24.1 -dj-database-url==0.4.1 Django==1.9.10 -django-cors-headers==1.2.2 -django-pipeline==1.6.9 -docker-py==1.7.2 -dockerpty==0.4.1 -docopt==0.6.2 -docutils==0.12 -ecdsa==0.13 -Fabric==1.13.1 -futures==3.0.5 -GDAL==1.11.2 -geojson==1.3.3 -geojsonio==0.0.2 -gevent==1.1.2 -github3.py==0.9.3 -greenlet==0.4.10 -gunicorn==18.0 -jmespath==0.9.0 -meld3==1.0.2 -newrelic==2.40.0.34 -numpy==1.11.2 -pandas==0.19.0 -paramiko==1.17.2 -pathspec==0.3.4 -psycopg2==2.6.2 -pycrypto==2.6.1 -python-dateutil==2.5.3 -python-decouple==3.0 -python-memcached==1.58 -pytz==2016.7 -PyYAML==3.12 -requests==2.9.1 -semantic-version==2.5.0 -Shapely==1.5.17 -six==1.8.0 -SQLAlchemy==1.1.2 -supervisor==3.3.1 -texttable==0.8.6 -unicodecsv==0.14.1 -uritemplate==3.0.0 -uritemplate.py==3.0.2 -wazimap==0.5.2 -wcwidth==0.1.7 -websocket-client==0.37.0 -whitenoise==3.2.2 -xlrd==1.0.0 +numpy==1.14.4 +Shapely==1.6.4.post1 +wazimap==1.1.1 +gevent==1.3.3 +django-leaflet==0.24.0 +django-jsonify==0.3.0 +futures==3.2.0 +psycopg2==2.7.4 +python-decouple==3.1 + diff --git a/sql/age_area_sex.sql b/sql/age_area_sex.sql index 23e7090..e53e83a 100644 --- a/sql/age_area_sex.sql +++ b/sql/age_area_sex.sql @@ -25,6 +25,7 @@ SET default_with_oids = false; CREATE TABLE age_area_sex ( geo_level character varying(15) NOT NULL, geo_code character varying(10) NOT NULL, + geo_version character varying(100) DEFAULT '2011'::character varying NOT NULL, age character varying(40) NOT NULL, area character varying(10) NOT NULL, sex character varying(10) NOT NULL, @@ -47803,7 +47804,7 @@ IN,country,Age not stated,Urban,Male,839461 -- ALTER TABLE ONLY age_area_sex - ADD CONSTRAINT age_area_sex_pkey PRIMARY KEY (geo_level, geo_code, area, age, sex); + ADD CONSTRAINT age_area_sex_pkey PRIMARY KEY (geo_level, geo_code, geo_version, area, age, sex); -- diff --git a/sql/education_area_sex.sql b/sql/education_area_sex.sql index e1aacd7..3493421 100644 --- a/sql/education_area_sex.sql +++ b/sql/education_area_sex.sql @@ -25,6 +25,7 @@ SET default_with_oids = false; CREATE TABLE area_education_sex ( geo_level character varying(15) NOT NULL, geo_code character varying(10) NOT NULL, + geo_version character varying(100) DEFAULT '2011'::character varying NOT NULL, area character varying(10) NOT NULL, sex character varying(10) NOT NULL, education character varying(50) NOT NULL, @@ -27087,7 +27088,7 @@ IN,country,Urban,Female,Unclassified,462682 -- ALTER TABLE ONLY area_education_sex - ADD CONSTRAINT area_education_sex_pkey PRIMARY KEY (geo_level, geo_code, area, education, sex); + ADD CONSTRAINT area_education_sex_pkey PRIMARY KEY (geo_level, geo_code, geo_version, area, education, sex); -- diff --git a/sql/geography.sql b/sql/geography.sql index c34fa37..a3c0cca 100644 --- a/sql/geography.sql +++ b/sql/geography.sql @@ -11,6 +11,7 @@ SET client_min_messages = warning; SET search_path = public, pg_catalog; +DROP INDEX IF EXISTS public.wazimap_geography_version_01953818_like; DROP INDEX IF EXISTS public.wazimap_geography_name_36b79089_like; DROP INDEX IF EXISTS public.wazimap_geography_2fc6351a; DROP INDEX IF EXISTS public.wazimap_geography_84cdc76c; @@ -40,7 +41,8 @@ CREATE TABLE wazimap_geography ( square_kms double precision, parent_level character varying(15), parent_code character varying(10), - long_name character varying(100) + long_name character varying(100), + version character varying(100) DEFAULT '2011'::character varying NOT NULL ); @@ -759,7 +761,7 @@ SELECT pg_catalog.setval('wazimap_geography_id_seq', 1, false); -- ALTER TABLE ONLY wazimap_geography - ADD CONSTRAINT wazimap_geography_geo_level_9a5128d2_uniq UNIQUE (geo_level, geo_code); + ADD CONSTRAINT wazimap_geography_geo_level_9a5128d2_uniq UNIQUE (geo_level, geo_code , version); -- @@ -770,7 +772,13 @@ ALTER TABLE ONLY wazimap_geography ADD CONSTRAINT wazimap_geography_pkey PRIMARY KEY (id); -- --- Name: wazimap_geography_2fc6351a; Type: INDEX; Schema: public; Owner: factlyin; Tablespace: +-- Name: wazimap_geography_2af72f10; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX wazimap_geography_2af72f10 ON wazimap_geography USING btree (version); + +-- +-- Name: wazimap_geography_2fc6351a; Type: INDEX; Schema: public; Owner: wazimap; Tablespace: -- CREATE INDEX wazimap_geography_2fc6351a ON wazimap_geography USING btree (long_name); @@ -799,4 +807,3 @@ CREATE INDEX wazimap_geography_name_36b79089_like ON wazimap_geography USING btr -- -- PostgreSQL database dump complete -- - diff --git a/sql/maritalstatus_area_sex.sql b/sql/maritalstatus_area_sex.sql index 9cb18ac..d15b0b1 100644 --- a/sql/maritalstatus_area_sex.sql +++ b/sql/maritalstatus_area_sex.sql @@ -25,6 +25,7 @@ SET default_with_oids = false; CREATE TABLE area_maritalstatus_sex ( geo_level character varying(15) NOT NULL, geo_code character varying(10) NOT NULL, + geo_version character varying(100) DEFAULT '2011'::character varying NOT NULL, area character varying(10) NOT NULL, sex character varying(10) NOT NULL, maritalstatus character varying(50) NOT NULL, @@ -16271,7 +16272,7 @@ IN,country,Urban,Female,unspecified,0 -- ALTER TABLE ONLY area_maritalstatus_sex - ADD CONSTRAINT area_maritalstatus_sex_pkey PRIMARY KEY (geo_level, geo_code, area, maritalstatus, sex); + ADD CONSTRAINT area_maritalstatus_sex_pkey PRIMARY KEY (geo_level, geo_code, geo_version, area, maritalstatus, sex); -- diff --git a/sql/pca_area_sex_literecy_type.sql b/sql/pca_area_sex_literecy_type.sql index 9da66b9..35df280 100644 --- a/sql/pca_area_sex_literecy_type.sql +++ b/sql/pca_area_sex_literecy_type.sql @@ -25,6 +25,7 @@ SET default_with_oids = false; CREATE TABLE area_literacy_sex ( geo_level character varying(15) NOT NULL, geo_code character varying(10) NOT NULL, + geo_version character varying(100) DEFAULT '2011'::character varying NOT NULL, area character varying(10) NOT NULL, literacy character varying(20) NOT NULL, sex character varying(10) NOT NULL, @@ -5455,7 +5456,7 @@ IN,country,Rural,Female,Illiterate,204535333 -- ALTER TABLE ONLY area_literacy_sex - ADD CONSTRAINT area_literacy_sex_pkey PRIMARY KEY (geo_level, geo_code, area, literacy, sex); + ADD CONSTRAINT area_literacy_sex_pkey PRIMARY KEY (geo_level, geo_code, geo_version, area, literacy, sex); -- diff --git a/sql/population_area.sql b/sql/population_area.sql index 91da797..350bfe3 100644 --- a/sql/population_area.sql +++ b/sql/population_area.sql @@ -25,6 +25,7 @@ SET default_with_oids = false; CREATE TABLE area_sex ( geo_level character varying(15) NOT NULL, geo_code character varying(10) NOT NULL, + geo_version character varying(100) DEFAULT '2011'::character varying NOT NULL, area character varying(10) NOT NULL, sex character varying(10) NOT NULL, total integer NOT NULL @@ -2750,7 +2751,7 @@ IN,country,Rural,Female,405967794 -- ALTER TABLE ONLY area_sex - ADD CONSTRAINT area_sex_pkey PRIMARY KEY (geo_level, geo_code, area, sex); + ADD CONSTRAINT area_sex_pkey PRIMARY KEY (geo_level, geo_code, geo_version, area, sex); -- diff --git a/sql/religion_pca_area_sex.sql b/sql/religion_pca_area_sex.sql index 29f2dc6..1a4364b 100644 --- a/sql/religion_pca_area_sex.sql +++ b/sql/religion_pca_area_sex.sql @@ -25,6 +25,7 @@ SET default_with_oids = false; CREATE TABLE area_religion_sex ( geo_level character varying(15) NOT NULL, geo_code character varying(10) NOT NULL, + geo_version character varying(100) DEFAULT '2011'::character varying NOT NULL, religion character varying(40) NOT NULL, area character varying(10) NOT NULL, sex character varying(10) NOT NULL, @@ -21679,7 +21680,7 @@ IN,country,Religion not stated,Urban,Female,604075 -- ALTER TABLE ONLY area_religion_sex - ADD CONSTRAINT area_religion_sex_pkey PRIMARY KEY (geo_level, geo_code, area, religion, sex); + ADD CONSTRAINT area_religion_sex_pkey PRIMARY KEY (geo_level, geo_code, geo_version, area, religion, sex); -- diff --git a/sql/rural_population.sql b/sql/rural_population.sql index c8b0448..e67a559 100644 --- a/sql/rural_population.sql +++ b/sql/rural_population.sql @@ -25,6 +25,7 @@ SET default_with_oids = false; CREATE TABLE ruralpopulation ( geo_level character varying(15) NOT NULL, geo_code character varying(10) NOT NULL, + geo_version character varying(100) DEFAULT '2011'::character varying NOT NULL, villages integer NOT NULL, "rural population" character varying(10) NOT NULL, total integer NOT NULL @@ -1398,7 +1399,7 @@ IN,country,597608,Female,405967794 -- ALTER TABLE ONLY ruralpopulation - ADD CONSTRAINT ruralpopulation_pkey PRIMARY KEY (geo_level, geo_code, villages, "rural population"); + ADD CONSTRAINT ruralpopulation_pkey PRIMARY KEY (geo_level, geo_code, geo_version, villages, "rural population"); -- diff --git a/sql/workers_area_sex.sql b/sql/workers_area_sex.sql index 166256c..dd0201d 100644 --- a/sql/workers_area_sex.sql +++ b/sql/workers_area_sex.sql @@ -25,6 +25,7 @@ SET default_with_oids = false; CREATE TABLE area_workers_workerssex ( geo_level character varying(15) NOT NULL, geo_code character varying(10) NOT NULL, + geo_version character varying(100) DEFAULT '2011'::character varying NOT NULL, area character varying(10) NOT NULL, workerssex character varying(10) NOT NULL, workers character varying(50) NOT NULL, @@ -16271,7 +16272,7 @@ IN,country,Urban,Female,Non-workers available for work,13155932 -- ALTER TABLE ONLY area_workers_workerssex - ADD CONSTRAINT area_workers_workerssex_pkey PRIMARY KEY (geo_level, geo_code, area, workers, workerssex); + ADD CONSTRAINT area_workers_workerssex_pkey PRIMARY KEY (geo_level, geo_code, geo_version, area, workers, workerssex); --