Migrating from Access
dpmcore can import data from Microsoft Access .accdb / .mdb files
into any SQLAlchemy-supported database (SQLite, PostgreSQL, SQL Server).
Prerequisites
You need one of the following backends to read Access files:
Backend |
Platform |
Install |
|---|---|---|
mdb-tools |
Linux |
|
pyodbc + Access ODBC driver |
Windows / macOS |
|
The service tries mdb-tools first, then falls back to pyodbc.
You also need pandas:
pip install dpmcore[migration]
Using the CLI
The simplest way to run a migration:
dpmcore migrate --source /path/to/dpm.accdb --database sqlite:///dpm.db
This will:
Read all user tables from the Access file (system tables are skipped).
Create the ORM schema in the target database.
Load the data using
INSERT(preserving ORM column types).Display a summary table with row counts per table.
Example output:
Migration Results
┌──────────────────────┬───────┐
│ Table │ Rows │
├──────────────────────┼───────┤
│ Release │ 8 │
│ Framework │ 3 │
│ Module │ 42 │
│ Table │ 312 │
│ ... │ ... │
└──────────────────────┴───────┘
Total: 58 tables, 145230 rows (backend: mdbtools)
Using the Python API
Via DpmConnection
from dpmcore import connect
with connect("postgresql://user:pass@host/dpm_db") as db:
result = db.services.migration.migrate_from_access(
"/path/to/dpm.accdb"
)
print(f"Tables: {result.tables_migrated}")
print(f"Rows: {result.total_rows}")
print(f"Backend: {result.backend_used}")
for name, count in result.table_details.items():
print(f" {name}: {count} rows")
if result.warnings:
for w in result.warnings:
print(f" WARNING: {w}")
Standalone (without DpmConnection)
from sqlalchemy import create_engine
from dpmcore.loaders.migration import MigrationService
engine = create_engine("sqlite:///dpm.db")
service = MigrationService(engine)
result = service.migrate_from_access("/path/to/dpm.accdb")
MigrationResult
The MigrationResult dataclass contains:
Field |
Type |
Description |
|---|---|---|
|
|
Number of tables loaded |
|
|
Total row count across all tables |
|
|
Table name to row count mapping |
|
|
Any non-fatal issues encountered |
|
|
|
How it works
Extract — Tables are read from the Access file using mdb-tools (
mdb-tables+mdb-export) or pyodbc. Access system tables (MSys*,~*) are automatically filtered out.Create schema —
Base.metadata.create_all(engine)creates all ORM tables if they don’t exist yet.Load data — Each table’s DataFrame is written with
df.to_sql(..., if_exists="append"). Theappendmode preserves ORM-created column types and constraints.
Type handling
mdb-tools backend: CSV data is read as strings, then numeric columns are auto-detected via
pd.to_numeric.pyodbc backend: Column types from the Access schema metadata (
cursor.description) are used to enforce types. Text columns that contain numeric-looking values (e.g. postal codes"01234") are preserved as strings.
Error handling
If neither mdb-tools nor pyodbc can read the file, a
MigrationErroris raised.If individual tables fail to load, a warning is recorded in
result.warningsbut the migration continues.