Geo data (geo_data module)¶
A bundled module that ships seed data for the world's geography: 7 continents, ~250 countries (with ISO-3, phone code, currency, capital, population, flag emoji), ~5,000 states / provinces (ISO 3166-2), and ~6,000 cities (every country capital plus every city with population ≥ 100,000).
Install¶
The module depends on two upstream packages that aren't part of the default pyvelm wheel — install the geo extras first:
Then install the module from Apps, or include it in your
loader.load_and_install(...) call. Whenever pyvelm[geo] is present,
the bundled GeographyDatabaseSeeder runs on install, upgrade,
and Sync. By default only continents and your detected country
are inserted (PYVELM_GEO_SEED_LEVEL=bootstrap). Set
PYVELM_GEO_COUNTRY=KE to pin the country when auto-detection is wrong.
Without the geo extras, the module installs but seeding is skipped until
you pip install pyvelm[geo] and Sync or run pyvelm db seed geo_data.
You can also open Settings → Geography → Countries and click
Seed geography data (superuser). That starts a background import of
all countries, states, and cities from geonamescache + pycountry — a
toast confirms it started; refresh the list after about a minute.
The seed is idempotent: existing rows are matched on their
natural keys (continent code, country code, state code, city
geoname_id) and only the missing ones are inserted. Inserts use
batched SQL (not one ORM create() per row). After the first full
load, install/upgrade/Sync skips the seeder when ~200+ countries are
already present. Use Seed geography data or seed_reference_data()
to force a refresh (countries are patched with upstream field updates).
PYVELM_GEO_SEED_LEVEL |
What install/Sync seeds |
|---|---|
bootstrap (default) |
7 continents + detected country (or PYVELM_GEO_COUNTRY) |
countries |
Continents + all ~250 countries |
states |
Above + ISO subdivisions |
full |
Above + major cities |
For faster CI, pytest sets PYVELM_GEO_SEED_LEVEL=countries. Use
Seed geography data or geo_seed_level="full" for the complete dataset.
Models¶
| Model | Rows | Identity | Notes |
|---|---|---|---|
res.continent |
7 | code (AF, AS, EU, NA, SA, OC, AN) |
Matches GeoNames' continentCode. |
res.country (extended) |
~250 | code (ISO 3166-1 alpha-2) |
Adds continent_id, iso3, phone_code, currency_code, capital, population, flag_emoji. The legacy region_id stays for backward compatibility. |
res.country.state |
~5,000 | code (ISO 3166-2, e.g. US-CA) |
short_code is the part after the dash (CA). type carries pycountry's label (State, Province, Region, …). |
res.city |
~6,000 | geoname_id |
is_capital is True for the country's capital city. latitude / longitude are stored as Float. |
display_name is overridden on every model so combobox pickers
render usefully out of the box:
| Model | Format |
|---|---|
res.continent |
{name} ({code}) |
res.country |
{flag_emoji} {name} |
res.country.state |
{name} ({short_code}) |
res.city |
{name}, {state.short_code or country.code} |
Country form (notebook demo)¶
The Countries form (geo_data.country.form) demonstrates Form UX
features:
- Flat Identity and Facts sections for scalar fields.
- A Subdivisions notebook with States / provinces and Cities tabs.
state_idsandcity_idseach useedit_toggle=Truewith compact list views (geo_data.state.compact,geo_data.city.compact) so users can switch between dialog lines and an inline grid on the parent Edit form.
After upgrading to geo_data 0.1.3+, run pyvelm db migrate (or Apps →
Sync) so ir.ui.view picks up the arch.
Sidebar¶
Adds Settings → Geography with four leaves:
- Continents
- Countries
- States / provinces
- Cities
ACL: Admin gets full CRUD on all four models; User gets read so non-admins can reference geo rows from their own forms even though they can't edit them.
Data sources¶
geonamescache— continents, countries (withcontinent,iso3,phone,currencycode,capital,population), and ~32,000 cities. The seeder filters cities to capitals + population ≥ 100,000 by default; raise that threshold by editing the module or call_seed_cities()yourself if you need a larger set.pycountry— authoritative ISO 3166-2 subdivisions, joined to countries by ISO alpha-2.
Usage from your own modules¶
from pyvelm import BaseModel, Char, Many2one
class Customer(BaseModel):
_name = "crm.customer"
name = Char(required=True)
country_id = Many2one("res.country")
state_id = Many2one("res.country.state")
city_id = Many2one("res.city")
The standard Many2one combobox already searches by display_name,
so picking "California" or "🇫🇷 France" works without any extra
widget configuration.