-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Maj tracés réseaux #929
base: dev
Are you sure you want to change the base?
The head ref may contain hidden characters: "maj_trac\u00E9s_r\u00E9seaux"
Maj tracés réseaux #929
Changes from all commits
d504677
0f00803
0cbce55
c1eb08d
e74ff3e
8b31735
911464f
692856e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,7 +15,7 @@ | |
3. Mise à jour des données sur les réseaux depuis Airtable | ||
- Si la table des réseaux a été mise à jour lors de l'étape précédente : `yarn cli update-networks network` | ||
- Sinon | ||
- `yarn cli download-network network` | ||
- `yarn cli download-update-network network` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. J'ai changé un peu le processus, et je voulais que download-network (= synchro de airtable vers postgres) n'ait pas d'effets de bord et ne modifie pas airtable. J'ai donc changé la commande référencée ici. |
||
- Normalement ce script complète la table *zones_et_reseaux_en_construction* et regénère la table *zones_et_reseaux_en_construction_tiles* | ||
- /!\\ Note : pour les **réseaux de chaleur**, il faut [générer les tuiles différemment](./génération_tuiles_réseaux_de_chaleur.md). | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,9 +9,11 @@ import { DatabaseTileInfo, DatabaseSourceId, tilesInfo, zDatabaseSourceId } from | |
import { KnownAirtableBase, knownAirtableBases } from './airtable/bases'; | ||
import { createModificationsReseau } from './airtable/create-modifications-reseau'; | ||
import { fetchBaseSchema } from './airtable/dump-schema'; | ||
import { downloadNetwork } from './networks/download-network'; | ||
import { downloadNetwork, downloadUpdateNetwork } from './networks/download-network'; | ||
import { generateTilesFromGeoJSON } from './networks/generate-tiles'; | ||
import { applyGeometryUpdates } from './networks/geometry-updates'; | ||
import { importMvtDirectory } from './networks/import-mvt-directory'; | ||
import { syncPostgresToAirtable } from './networks/sync-pg-to-airtable'; | ||
import { upsertFixedSimulateurData } from './simulateur/import'; | ||
import { fillTiles } from './utils/tiles'; | ||
|
||
|
@@ -45,11 +47,18 @@ program | |
await downloadNetwork(table); | ||
}); | ||
|
||
program | ||
.command('download-update-network') | ||
.argument('<network-id>', 'Network id', validateNetworkId) | ||
.action(async (table) => { | ||
await downloadUpdateNetwork(table); | ||
}); | ||
|
||
program | ||
.command('fill-tiles') | ||
.argument('<network-id>', 'Network id', (v) => zDatabaseSourceId.parse(v)) | ||
.argument('[zoomMin]', 'Minimum zoom', parseInt, 0) | ||
.argument('[zoomMax]', 'Maximum zoom', parseInt, 17) | ||
.argument('[zoomMin]', 'Minimum zoom', (v) => parseInt(v), 0) | ||
.argument('[zoomMax]', 'Maximum zoom', (v) => parseInt(v), 17) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. En fait il n'y a pas que v qui est passé en argument et ça passait directement en 2e argument de parseInt comme base. Et on veut pas ça... |
||
.argument('[withIndex]', 'With index', (v) => !!v, false) | ||
.action(async (table, zoomMin, zoomMax, withIndex) => { | ||
await db((tilesInfo[table] as DatabaseTileInfo).tiles).delete(); | ||
|
@@ -86,8 +95,8 @@ program | |
.command('generate-tiles-from-file') | ||
.argument('<fileName>', 'input file (format GeoJSON)') | ||
.argument('<destinationTable>', 'Destination table') | ||
.argument('[zoomMin]', 'Minimum zoom', parseInt, 0) | ||
.argument('[zoomMax]', 'Maximum zoom', parseInt, 17) | ||
.argument('[zoomMin]', 'Minimum zoom', (v) => parseInt(v), 0) | ||
.argument('[zoomMax]', 'Maximum zoom', (v) => parseInt(v), 17) | ||
.action(async (fileName, destinationTable, zoomMin, zoomMax) => { | ||
const geojson = JSON.parse(await readFile(fileName, 'utf8')); | ||
|
||
|
@@ -117,15 +126,39 @@ program | |
program | ||
.command('update-networks') | ||
.argument('<network-id>', 'Network id', (v) => zDatabaseSourceId.parse(v)) | ||
.argument('[zoomMin]', 'Minimum zoom', parseInt, 0) | ||
.argument('[zoomMax]', 'Maximum zoom', parseInt, 17) | ||
.argument('[zoomMin]', 'Minimum zoom', (v) => parseInt(v), 0) | ||
.argument('[zoomMax]', 'Maximum zoom', (v) => parseInt(v), 17) | ||
.argument('[withIndex]', 'With index', (v) => !!v, false) | ||
.action(async (table, zoomMin, zoomMax, withIndex) => { | ||
await downloadNetwork(table); | ||
await downloadUpdateNetwork(table); | ||
await db((tilesInfo[table] as DatabaseTileInfo).tiles).delete(); | ||
await fillTiles(table, zoomMin, zoomMax, withIndex); | ||
}); | ||
|
||
program | ||
.command('apply-geometry-updates') | ||
.option('--dry-run', 'Run the command in dry-run mode', false) | ||
.action(async ({ dryRun }) => { | ||
try { | ||
await applyGeometryUpdates(dryRun); | ||
} catch (err) { | ||
console.error('err', err); | ||
process.exit(2); | ||
} | ||
}); | ||
|
||
program | ||
.command('sync-postgres-to-airtable') | ||
.option('--dry-run', 'Run the command in dry-run mode', false) | ||
.action(async ({ dryRun }) => { | ||
try { | ||
await syncPostgresToAirtable(dryRun); | ||
} catch (err) { | ||
console.error('err', err); | ||
process.exit(2); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Je pensais qu'il y avait un catch global pour chaque action mais que nenni. Il faudrait que ça soit global pour pas s'embêter avec des try catch. |
||
}); | ||
|
||
program | ||
.command('update-simulateur') | ||
.description('Take AMORCE file and either create records in database or update them.') | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,7 +11,7 @@ table=$2 | |
options=$3 | ||
if [[ $env != "dev" && $env != "prod" ]]; then | ||
usage | ||
exit 1+ | ||
exit 1 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typo d'origine 👏 |
||
fi | ||
|
||
if [[ "$table" = "" ]]; then | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,15 +6,15 @@ import db from 'src/db'; | |
import base from 'src/db/airtable'; | ||
import { DatabaseTileInfo, tilesInfo, DatabaseSourceId } from 'src/services/tiles.config'; | ||
|
||
const TypeArray: unique symbol = Symbol('array'); | ||
const TypeBool: unique symbol = Symbol('bool'); | ||
const TypeJSONArray: unique symbol = Symbol('json'); | ||
const TypeNumber: unique symbol = Symbol('number'); | ||
const TypePercentage: unique symbol = Symbol('percentage'); | ||
const TypeString: unique symbol = Symbol('string'); | ||
const TypeStringToArray: unique symbol = Symbol('array'); | ||
export const TypeArray: unique symbol = Symbol('array'); | ||
export const TypeBool: unique symbol = Symbol('bool'); | ||
export const TypeJSONArray: unique symbol = Symbol('json'); | ||
export const TypeNumber: unique symbol = Symbol('number'); | ||
export const TypePercentage: unique symbol = Symbol('percentage'); | ||
export const TypeString: unique symbol = Symbol('string'); | ||
export const TypeStringToArray: unique symbol = Symbol('array'); | ||
|
||
type Type = | ||
export type Type = | ||
| typeof TypeArray | ||
| typeof TypeBool | ||
| typeof TypeJSONArray | ||
|
@@ -32,7 +32,7 @@ const conversionConfigReseauxDeChaleur = { | |
'reseaux classes': TypeBool, | ||
has_PDP: TypeBool, | ||
nom_reseau: TypeString, | ||
communes: TypeStringToArray, | ||
// communes: TypeStringToArray, | ||
MO: TypeString, | ||
Gestionnaire: TypeString, | ||
'Taux EnR&R': TypeNumber, | ||
|
@@ -48,7 +48,7 @@ const conversionConfigReseauxDeChaleur = { | |
'Dev_reseau%': TypeNumber, | ||
'Rend%': TypeNumber, | ||
reseaux_techniques: TypeBool, | ||
departement: TypeNumber, | ||
departement: TypeString, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. La colonne departement contenait jusque là des codes départements / codes postaux. Et ça contient maintenant des labels... Du coup j'ai changé le type, et il faudra dans le futur compléter cette information automatiquement. C'est utilisé que côté airtable. |
||
region: TypeString, | ||
adresse_mo: TypeString, | ||
CP_MO: TypeString, | ||
|
@@ -114,12 +114,12 @@ const conversionConfigReseauxDeFroid = { | |
//has_trace: TypeBool, | ||
'Taux EnR&R': TypeNumber, | ||
Gestionnaire: TypeString, | ||
communes: TypeStringToArray, | ||
// communes: TypeStringToArray, | ||
contenu_CO2_2023_tmp: TypeNumber, | ||
contenu_CO2_ACV_2023_tmp: TypeNumber, | ||
'contenu CO2': TypeNumber, | ||
'contenu CO2 ACV': TypeNumber, | ||
departement: TypeNumber, | ||
departement: TypeString, | ||
region: TypeString, | ||
MO: TypeString, | ||
adresse_mo: TypeString, | ||
|
@@ -146,7 +146,7 @@ const conversionConfigReseauxDeFroid = { | |
const conversionConfigAutres = { | ||
mise_en_service: TypeString, | ||
gestionnaire: TypeString, | ||
communes: TypeStringToArray, | ||
// communes: TypeStringToArray, | ||
is_zone: TypeBool, | ||
} as const; | ||
|
||
|
@@ -160,6 +160,35 @@ export const downloadNetwork = async (table: DatabaseSourceId) => { | |
} | ||
const networksAirtable = await base(tileInfo.airtable).select().all(); | ||
|
||
const logger = parentLogger.child({ | ||
table: table, | ||
count: networksAirtable.length, | ||
}); | ||
const startTime = Date.now(); | ||
logger.info('start network update'); | ||
await Promise.all( | ||
networksAirtable.map(async (network) => { | ||
if (network.get('id_fcu')) { | ||
await db(tileInfo.table).update(convertEntityFromAirtableToPostgres(table, network)).where('id_fcu', network.get('id_fcu')); | ||
} | ||
}) | ||
); | ||
logger.info('end network update', { | ||
duration: Date.now() - startTime, | ||
}); | ||
}; | ||
|
||
/** | ||
* Synchronise les données d'une table réseau dans Airtable vers la table correspondante dans Postgres (identique downloadNetwork) | ||
* Met également à jour certains champs côté airtable (spécifiques à chaque table). | ||
*/ | ||
export const downloadUpdateNetwork = async (table: DatabaseSourceId) => { | ||
const tileInfo = tilesInfo[table] as DatabaseTileInfo; | ||
if (!tileInfo || !tileInfo.airtable) { | ||
throw new Error(`${table} not managed`); | ||
} | ||
const networksAirtable = await base(tileInfo.airtable).select().all(); | ||
|
||
const logger = parentLogger.child({ | ||
table: table, | ||
count: networksAirtable.length, | ||
|
@@ -270,7 +299,7 @@ function convertEntityFromAirtableToPostgres(type: DatabaseSourceId, airtableNet | |
/** | ||
* Convertit et corrige le potentiel mauvais typage côté Airtable. | ||
*/ | ||
function convertAirtableValue(value: any, type: Type) { | ||
export function convertAirtableValue(value: any, type: Type) { | ||
switch (type) { | ||
case TypeArray: | ||
return value instanceof Array ? value : []; | ||
|
@@ -288,5 +317,7 @@ function convertAirtableValue(value: any, type: Type) { | |
return value !== undefined && value !== null && value !== 'NULL' ? value : null; | ||
case TypeStringToArray: | ||
return value !== undefined && value !== null && value !== 'NULL' ? value.split(',') : []; | ||
default: | ||
throw new Error(`invalid type ${type}`); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A un moment donné, on avait besoin de l'énergie majoritaire, mais ce n'est plus le cas, donc on simplifie la requête.