Skip to content

pyvelm v0.18.0

Release date: 2026-05-27

A bundled geo_data module that seeds the world's geography out of the box, plus a small framework fix so cross-module _inherit can grow new Many2one columns without re-ordering hacks.


Highlights

geo_data module

A new bundled module — opt in with pip install pyvelm[geo] and install from Apps:

Model Rows Notes
res.continent 7 Code matches GeoNames (AF, AS, EU, NA, SA, OC, AN).
res.country (extended) ~250 Adds continent_id, iso3, phone_code, currency_code, capital, population, flag_emoji.
res.country.state ~5,000 ISO 3166-2 subdivisions. code="US-CA", short_code="CA", type from pycountry.
res.city ~6,000 Every country capital + every city with population ≥ 100,000. latitude/longitude/population/timezone/geoname_id.

Sidebar adds Settings → Geography → Continents / Countries / States / Cities. ACL: Admin gets full CRUD on all four models; User gets read so non-admins can pick geo rows from their own forms.

display_name is set on every model so the standard m2o combobox renders usefully out of the box:

  • res.continentEurope (EU)
  • res.country🇫🇷 France
  • res.country.stateCalifornia (CA)
  • res.cityBerlin, BE

Use from your own modules:

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 install hook is idempotent: it matches on natural ids (continent code, country code, state code, city geoname_id) and only inserts the missing rows. Re-installing the module after a pyvelm upgrade picks up upstream fixes from GeoNames / pycountry.

Cross-module FK ordering fix

BaseModel._setup_foreign_keys now probes information_schema.tables for the target table and skips the constraint when the table doesn't exist yet. The extending module's own install pass re-runs FK setup on the extended model (via _model_extensions), so the constraint lands exactly once at the right time.

Before this release, a downstream module that did:

class Country(BaseModel):
    _inherit = "res.country"
    continent_id = Many2one("res.continent", ondelete="SET NULL")

would crash base's install with UndefinedTable: relation "res_continent" does not exist, because model loading runs before any install, but base's FK setup tries to create the constraint before geo_data had a chance to create the table.

The fix is general — any future module that grows new Many2one columns on a base-owned model with comodels it owns itself will work without splitting the model definition across modules.


Upgrade

pip install -U pyvelm[geo]==0.18.0
  1. Apps → Install geo_data (depends on base + admin). No base schema bumps.
  2. The seed runs in one transaction — first install of geo_data inserts ~11,000 rows. Re-installing later patches existing rows with any new upstream fields.
  3. Hard-refresh the browser so the new sidebar entries appear.

Also in this release

  • pyvelm/geo_utils.py ships flag_emoji, geo_packages_available, require_geo_packages as top-level helpers so unit tests can import them without going through the poisoned pyvelm.modules namespace.
  • pyvelm/tests/test_geo_data.py covers flag_emoji (US, lowercase, invalid inputs) + require_geo_packages extras check.

Docs