Compare commits

..

68 Commits

Author SHA1 Message Date
45755bf797 Correction of finding postcode + set the center postcode as coordinates for address without reference 2025-09-16 13:41:48 +02:00
08e87503f0 Correction: do not attribute center_id = 1 to person 2025-09-16 10:52:37 +02:00
20517a109b Improved person import with the linkage to reference addresses 2025-09-02 12:42:29 +02:00
c17b2ae524 FIXED import person with the new gender entity 2025-09-02 11:03:35 +02:00
5bfc7f4a02 Small typos in import.sql 2025-08-29 13:01:54 +02:00
6b8ca0caa3 Add sql for third party 2025-08-14 18:14:13 +02:00
nobohan
c5f892c27d FEATURE import users 2025-07-11 15:53:40 +02:00
nobohan
82f69f9845 FEATURE add sql for import location_type and location 2025-07-11 11:48:24 +02:00
nobohan
fd4e68faa8 FEATURE ajout reprise de localisations - prepare 2025-07-10 16:21:06 +02:00
nobohan
3651b1a09b Improve/correct import SQL queries 2024-09-19 17:59:44 +02:00
nobohan
db52c72d22 Add another method to prepare the import tables 2024-09-17 15:37:16 +02:00
nobohan
9c90e5ac07 Add single python script for translating third party information into SQL 2024-02-16 09:48:07 +01:00
543a4569fd update script with resinam troubles 2023-05-05 17:16:30 +02:00
36e3bf3b4b modifs mineures du canevas sur les headers (v0.6.1) 2023-03-15 17:02:35 +01:00
ddfe9b53b3 Merge branch 'dev' 2023-03-15 13:25:29 +01:00
cea5190174 update readme 2023-03-15 13:24:52 +01:00
ca3ce608c0 Merge branch 'dev' 2023-03-15 10:25:12 +01:00
f3bda2a22e add readme 2023-03-15 10:24:39 +01:00
4e866c2d8e Merge branch 'dev' 2023-03-14 12:21:17 +01:00
6b11efd18e add v0.6.0 of excel canvas 2023-03-14 12:20:28 +01:00
290a9b917f Things to think when running script 2023-03-14 12:05:52 +01:00
b68e0399cc 62-63. Add and link comments to periods, pin last comment 2023-03-11 16:53:26 +01:00
07df6c4292 default value for socialissue_id, user_id, scope_id 2023-03-11 16:50:11 +01:00
d9152fc090 60. Link jobs to periods 2023-03-11 15:30:28 +01:00
12f0ec0ae4 59. Link origin to periods 2023-03-11 15:30:24 +01:00
264fdb5888 58. Link scopes to periods 2023-03-11 15:29:53 +01:00
7893eb3c81 57. Link referrer to periods 2023-03-11 13:43:44 +01:00
1adf47e63e 56. Link socialissues to periods 2023-03-11 13:42:38 +01:00
314e625c91 55. Copy period in period_location_history 2023-03-10 19:58:25 +01:00
59daee4790 53-54. Link period to person or temporary address location 2023-03-10 19:27:31 +01:00
6900d66206 52. Link participations to periods 2023-03-10 18:32:09 +01:00
f513dd1b36 Add a setval() query after INSERT INTO when id is not nextval() 2023-03-10 17:53:05 +01:00
67d020d322 50-51. Insert in accompanyingPeriods table 2023-03-10 17:51:58 +01:00
477565f6e1 Improve undo delete clause to avoid removing still referenced rows
(foreign key constraint violation)
2023-03-10 16:51:23 +01:00
e569d77bd2 Fix WHERE jsonb comparison 2023-03-10 16:20:58 +01:00
0ab77b77ed improve setval id if remove all rows 2023-03-10 16:18:51 +01:00
307cfcbe74 46. Add household composition 2023-03-10 16:17:27 +01:00
081ce76085 renaming alias 2023-03-10 16:16:27 +01:00
cadcddddb5 Improve date management for not specified dates
- use real import date for person createdat field
- use year first day for not specified startdate, comment date, etc.
2023-03-10 13:21:31 +01:00
dd3769e2a0 use validfrom in address insertion 2023-03-10 12:55:53 +01:00
1cc1b83435 add gendercomment in person insertion 2023-03-10 12:45:23 +01:00
9ac2553eb0 Fix phone numbers format 2023-03-10 12:16:51 +01:00
0c7ea76178 42. Insert query bloc for center history insertion 2023-03-08 23:44:39 +01:00
5f78276762 Rename aliases in undo queries 2023-03-08 23:43:47 +01:00
5a6daae5a4 43-44. Insert household and link to person, address, position 2023-03-08 21:20:52 +01:00
3978ee8b1a Fix WHERE jsonb comparison 2023-03-08 21:20:47 +01:00
838bcb78ff 33-34 Fix phone format 2023-03-08 21:08:02 +01:00
f3170d0c87 cleaning 2023-03-08 18:16:55 +01:00
1a6f3953ca 42. Add address, and link it to person 2023-03-01 21:20:49 +01:00
139dd6209a 33-34. Format phone numbers 2023-03-01 20:57:25 +01:00
25510c1efe fix query for person insertion 2023-03-01 20:56:53 +01:00
a36ee22be6 fix numberofchildren cast 2023-03-01 17:34:47 +01:00
b6f26900a7 20-32. Prepare import personnes and periodes tables 2023-03-01 17:18:00 +01:00
dd89aa6ff1 improve title comment block 2023-02-17 19:43:57 +01:00
4dc09c559a fix setval with coalesce (reset id too if no rows) 2023-02-17 19:28:00 +01:00
cb12f3000b 13. Complete chill_person_social_issue table 2023-02-17 19:23:38 +01:00
e14f6896e3 12. complete users table (referrer) 2023-02-17 19:23:38 +01:00
7b4f04ef40 11. complete scopes table 2023-02-17 19:22:45 +01:00
6d64060965 10. complete chill_main_user_job table 2023-02-17 19:22:38 +01:00
396444790f 9. complete chill_person_accompanying_period_origin table 2023-02-17 10:02:49 +01:00
44d24155a1 8. complete chill_person_accompanying_period_closingmotive table 2023-02-17 10:02:49 +01:00
32da5540fe 7. complete chill_person_household_position table 2023-02-17 10:02:49 +01:00
de8450267d 6. complete chill_person_household_composition_type table 2023-02-17 10:02:49 +01:00
27ef1034be 5. complete chill_person_marital_status table 2023-02-17 10:02:49 +01:00
40ebabf3f6 4. complete country table 2023-02-17 10:02:49 +01:00
9cd1f19f89 3. complete table chill_main_civility 2023-02-17 10:02:49 +01:00
06b0aab237 2. prepare date columns 2023-02-17 10:02:49 +01:00
f018a5d115 1. cast column id 2023-02-17 10:02:49 +01:00
11 changed files with 1469 additions and 5 deletions

0
.gitignore vendored Normal file → Executable file
View File

153
README.md Executable file
View File

@@ -0,0 +1,153 @@
CHILL - Reprise de données
==========================
Ce dépôt contient un script d'import qui s'applique à un canevas excel présenté au client. Le client remplit le fichier excel, puis le script insère les données dans la base de donnée.
L'opération est semi-automatique et réduit considérablement le temps dédié à l'import en structurant le format des données en entrée. Par contre il y a toujours une série de manipulations, pour préparer et insérer les données correctement.
Ces manipulations sont décrites ici.
Le client a rempli le canevas. Une relecture du fichier est toujours nécessaire afin de repérer les éventuelles irrégularités.
## 1. Préparer les fichiers csv
Le fichier se compose de plusieurs feuilles, chacune doit être sauvée au format csv.
Pour préparer les fichiers on va:
- nettoyer le fichier pour ne laisser en étiquette que les noms de colonnes en anglais. Il faut donc supprimer les 4 premières lignes de chaque fichier + la 6ème ligne.
(- ajouter une colonne de contôle en fin de ligne, par sécurité. Par exemple une colonne 'endcol' qui contient pour chaque cellule 'endrow'.)
- ajouter les doublequote lors de la sauvegarde du csv,
- enlever tous les line breaks et caractères spéciaux.
```bash
# Exemple de remplacements exécutés sur les fichiers csv pour un import spécifique :
$ sed -e :1 -e '$q' -e "/$CR\$/b" -e 'N;s/\n//;b1' < file.2.csv > file.3.csv
$ sed -e 's#"end"#"end"\n#g' < file.3.csv > file.4.csv
# Exemple pour un autre import:
$ cat file2.csv | sed -e 'N; s#_x000D_##g; s#\n##g; s/$CR//g' | tr "\n" " " > file3.csv
$ sed -e 's#"endcol"#"endcol"\n#g; s#"endrow"#"endrow"\n#g' < file3.csv > file4.csv
$ sed -e 's#^,##g; s#^ ##g' < file4.csv > file5.csv
```
## 2. Insérer les csv dans la base de donnée
On va insérer chaque feuille csv comme table à part entière d'un nouveau schéma `import`. On aura:
- import.choix_personnes
- import.personnes
- import.choix_periodes
- import.periodes
Pour réaliser cet import, on peut utiliser des outils tels que `pgfutter`, mais celui-ci peut s'avérer capricieux selon le fichier.
La meilleure méthode pour moi est de réaliser cette étape en local avec phpstorm, puis d'exporter le schéma `import` avec pg_dump avant de le transférer sur le serveur.
### 2.a Manipulations dans phpstorm
- S'il n'existe pas, créer le schéma `import`; s'il existe, s'assurer qu'il ne contient pas de tables ni de données.
#### Importer le csv dans la db
- ouvre le fichier csv > passe en onglet text > edit as table > set options:
- cocher 'first row is header'
- 'null value text': undefined (pas de champs null dans la table, mais un texte vide)
- then > open table
- import to database > set options:
- régler target/schema: import
- et table: même nom que le csv
- DDL: TEXT pour tous les champs
- then > import
#### Exporter en sql
- créer un fichier `<client>-data.sql` vide
- depuis chaque table du schéma `import`:
- copier le DDL de la table dans le fichier (s'assurer d'ajouter le préfixe `import.` sur chaque requête)
- export data > extractor: SQL-insert-multirow > copy to clipboard
- coller les données dans `<client>-data.sql`
### 2.b Avec des fonctions Postgresql
On peut aussi utiliser la fonction `\copy` de psql pour charger un fichier csv dans les tables temporaires du schéma "import".
Tout d'abord, les tables du schéma "import" doivent être préparées avec le script `prepare-import.sql`.
Puis on importe les fichiers csv:
```bash
psql chill-import
chill-import=# \copy "import".choix_personnes FROM 'choix_personnes.csv' DELIMITER ',' CSV HEADER
chill-import=# \copy "import".personnes FROM 'personnes.csv' DELIMITER ',' CSV HEADER
chill-import=# \copy "import".choix_periodes FROM 'choix_periodes.csv' DELIMITER ',' CSV HEADER
chill-import=# \copy "import".periodes FROM 'periodes.csv' DELIMITER ',' CSV HEADER
chill-import=# \copy "import".choix_localisations FROM 'choix_localisations.csv' DELIMITER ',' CSV HEADER
chill-import=# \copy "import".localisations FROM 'localisations.csv' DELIMITER ',' CSV HEADER
```
Enfin, on exporte la base de données en sql:
```bash
pg_dump chill-import --no-owner > <client>-data.sql
```
## 3. Import du schéma 'import' sur le serveur (safran)
- transférer le fichier `<client>-data.sql` sur le serveur (avec scp):
```bash
$ scp cyclo-data.sql debian@safran:~/data/tmp/
```
- faire une sauvegarde de la base sur laquelle on va réaliser l'insertion
```bash
debian@safran:~/bin$ bash backup_now_db.sh 5436 cycloprod
debian@safran:~/bin$ ls -l dump/ | tail -1
-rw-r--r-- 1 postgres postgres 234954230 Mar 15 10:40 20230315-104003_cycloprod.sql
```
ou bien simplement:
```bash
sudo su postgres
cd
pg_dump -p 5436 laplateformereunionprod > laplateformereunionprod.sql
```
- importer le fichier sql sur la base cible: `$ sudo su postgres -c 'psql -p5436'`
```sql
postgres=# \c cycloprod
You are now connected to database "cycloprod" as user "postgres".
cycloprod=# \dt import.*
Did not find any relation named "import.*".
cycloprod=# CREATE SCHEMA import;
-- insertion
cycloprod=# \i '/home/debian/data/tmp/cyclo-data.sql'
-- vérifier que le schéma import est en place
cycloprod=# \dt import.*
List of relations
Schema | Name | Type | Owner
--------+-----------------+-------+----------
import | choix_periodes | table | postgres
import | choix_personnes | table | postgres
import | periodes | table | postgres
import | personnes | table | postgres
(4 rows)
```
ou bien simplement:
```bash
sudo su postgres
psql -p 5436 laplateformereunionprod < /tmp/chill-import-lpreunion.sql
```
## 4. Exécution du script de migration
Se fait dans la console postgresql, en tant que user postgres, en étant connecté à la base de donnée cible.
On joue pas-à-pas les blocs de la section 'Up' du script `sql/import.sql`
## Tips
- Dans phpstorm, si on veut renommer le schéma pour ne pas tout mélanger, il vaut mieux faire 'Modify schema', car 'Rename' va faire des remplacements partout

Binary file not shown.

0
csv/choix_periodes.dist.csv Normal file → Executable file
View File

0
csv/choix_personnes.dist.csv Normal file → Executable file
View File

0
csv/periodes.dist.csv Normal file → Executable file
View File

0
csv/personnes.dist.csv Normal file → Executable file
View File

1048
sql/import.sql Normal file → Executable file

File diff suppressed because it is too large Load Diff

141
sql/prepare-import.sql Executable file
View File

@@ -0,0 +1,141 @@
CREATE SCHEMA "import";
CREATE TABLE "import".choix_personnes (
civility varchar(50) NULL,
gender varchar(50) NULL,
maritalstatus varchar(50) NULL,
country varchar(50) NULL,
household_composition_type varchar(50) NULL,
household_position varchar(50) NULL
);
CREATE TABLE "import".personnes (
id varchar(50) NULL,
civility varchar(50) NULL,
lastname varchar(50) NULL,
firstname varchar(50) NULL,
gender varchar(50) NULL,
gendercomment varchar(50) NULL,
nationality varchar(50) NULL,
memo varchar(50) NULL,
birthdate varchar(50) NULL,
place_of_birth varchar(50) NULL,
countryofbirth varchar(50) NULL,
deathdate varchar(50) NULL,
email varchar(50) NULL,
phonenumber varchar(50) NULL,
mobilenumber varchar(50) NULL,
contactinfo varchar(50) NULL,
street varchar(50) NULL,
extra varchar(50) NULL,
streetnumber varchar(50) NULL,
postcode varchar(50) NULL,
country varchar(50) NULL,
validfrom varchar(50) NULL,
maritalstatus varchar(50) NULL,
maritalstatuscomment varchar(50) NULL,
numberofchildren integer NULL,
household_composition_type varchar(50) NULL,
household_position varchar(50) NULL,
household_startdate varchar(50) NULL
);
CREATE TABLE "import".choix_periodes (
closingmotive varchar(50) NULL,
origin varchar(50) NULL,
acp_scopes varchar(50) NULL,
job varchar(50) NULL,
referrer varchar(50) NULL,
parent varchar(50) NULL,
enfant varchar(50) NULL,
acp_social_issues varchar(50) NULL,
work_social_action varchar(50) NULL,
street varchar(128) NULL,
extra varchar(50) NULL,
streetnumber integer NULL,
postcode integer NULL,
country varchar(50) NULL
);
CREATE TABLE "import".periodes (
id varchar(50) NULL,
nom varchar(50) NULL,
openingdate varchar(50) NULL,
closingdate varchar(50) NULL,
closingmotive varchar(50) NULL,
origin varchar(50) NULL,
remark integer NULL,
intensity varchar(50) NULL,
referrer varchar(50) NULL,
job varchar(50) NULL,
acp_scopes varchar(50) NULL,
"address" varchar(50) NULL,
personlocation varchar(50) NULL,
addresslocation varchar(50) NULL,
acp_socialissues varchar(50) NULL,
work_socialaction varchar(50) NULL,
comment1_content varchar(50) NULL,
comment2_content varchar(50) NULL,
comment3_content varchar(50) NULL,
comment4_content varchar(50) NULL,
comment5_content varchar(50) NULL
);
CREATE TABLE "import".choix_localisations (
title varchar(50) NULL,
"addressRequired" varchar(32) NULL,
"availableForUsers" boolean DEFAULT TRUE,
"contactData" varchar(32) NULL,
"defaultFor" varchar(32) NULL,
"editableByUsers" boolean DEFAULT TRUE
);
CREATE TABLE "import".localisations (
id varchar(50) NULL,
locname varchar(50) NULL,
phonenumber varchar(50) NULL,
phonenumber1 varchar(50) NULL,
email varchar(50) NULL,
loctype varchar(50) NULL,
street varchar(50) NULL,
extra varchar(50) NULL,
streetnumber varchar(50) NULL,
postcode varchar(50) NULL,
country varchar(50) NULL
);
CREATE TABLE "import".users (
id varchar(50) NULL,
"login" varchar(50) NULL,
civility varchar(50) NULL,
nom varchar(50) NULL,
prenom varchar(50) NULL,
libl varchar(50) NULL,
nom_prenom varchar(50) NULL,
phonenumber varchar(50) NULL,
email varchar(50) NULL,
metier varchar(50) NULL
);
CREATE TABLE "import".tiers (
ID INT PRIMARY KEY,
CATEGORIE VARCHAR(255),
SECTEUR_AS VARCHAR(255),
COMMUNE VARCHAR(255),
NOM VARCHAR(255),
PHONENUMBER VARCHAR(20),
PHONENUMBER_2 VARCHAR(20),
EMAIL VARCHAR(255),
PERSONNE_NOM VARCHAR(255),
PERSONNE_prenom VARCHAR(255),
PERSONNE_CIVILITE VARCHAR(20),
adresse TEXT,
CP VARCHAR(10),
TIERS_PARENT VARCHAR(255),
TIERS_PHYSIQUE_VS_MORALE VARCHAR(50),
POINT_DE_CONTACT_SUR_LE_TERRITOIRE TEXT,
COORDONNEES TEXT,
HORAIRES TEXT,
OBSERVATIONS TEXT
);

14
third_party/README.md vendored Executable file
View File

@@ -0,0 +1,14 @@
Import Third parties into Chill from the canvas
===============================================
This folder contains a single Python script that reads a csv file with Third party and print to the console some SQL to execute on the database.
The csv file should be simply exported from the sheet "Tiers" from the xls canvas.
Then, you can run the python script with adapting the following:
- name of the csv file to open
- change the mapping of third party categories, civilities and third party kinds according to your Chill database
So far, the addresses are not treated.

118
third_party/import_third_party_to_sql.py vendored Executable file
View File

@@ -0,0 +1,118 @@
import csv
print_to_screen = "INSERT INTO chill_3party.third_party (id, civility_id, name, firstname, name_company, acronym, kind, parent_id, profession, email, telephone, comment, contact_data_anonymous, active, created_at) VALUES"
def get_parent_id(arg):
return int(arg) + 1000 if arg else "NULL"
def get_third_party_civility(arg):
if arg == "Madame":
return 1
elif arg == "Monsieur":
return 2
elif arg == "Docteur":
return 3
else:
return "NULL"
def get_third_party_kind(arg):
if arg == "Tiers institutionnel":
return "company"
elif arg == "Personne de contact":
return "child"
elif arg == "Personne morale":
return "contact"
else:
return "company"
def make_bool_with_default_false(arg):
if arg == "oui":
return True
else:
return False
def make_telephone(arg):
if arg:
return f"'+32{arg}'"
else:
return "NULL"
with open("HalleDeHan_tiers.csv", newline="") as csv_file:
csv_reader = csv.reader(csv_file)
for skip in range(7):
next(csv_file)
for row in csv_reader:
third_party_id = int(row[0]) + 1000
civility = get_third_party_civility(row[1])
name = row[2]
firstname = row[3]
name_company = row[4]
acronym = row[5]
kind = get_third_party_kind(row[6])
parent_id = get_parent_id(row[7])
# row[8] is the name of the parent in the csv
profession = row[9]
# category = row[10] # category -> see below
email = row[11]
telephone = make_telephone(row[12])
# street = row[13] # TODO address
# extra = row[14]
# streetnumber = row[15]
# postcode = row[16]
# country = row[17]
# validfrom = row[18]
comment = row[19]
contact_data_anonymous = make_bool_with_default_false(row[20])
print_to_screen += f"({third_party_id}, {civility}, '{name}', '{firstname}', '{name_company}', '{acronym}', '{kind}', {parent_id}, '{profession}', '{email}', {telephone}, '{comment}', {contact_data_anonymous}, True, NOW()),"
print_to_screen = print_to_screen[:-1]
print(print_to_screen)
## categories
print_to_screen_cat = (
"INSERT INTO chill_3party.thirdparty_category (thirdparty_id, category_id) VALUES"
)
def get_third_party_category(arg):
if arg == "Stage vente":
return 2
elif arg == "Stage reassort":
return 8
elif arg == "Stage social / educ":
return 9
elif arg == "Stage logistique":
return 10
elif arg == "Stage bureautique":
return 11
else:
return None
with open("HalleDeHan_tiers.csv", newline="") as csv_file:
csv_reader = csv.reader(csv_file)
for skip in range(7):
next(csv_file)
for row in csv_reader:
third_party_id = int(row[0]) + 1000
category_id = get_third_party_category(row[10])
if category_id:
print_to_screen_cat += f"({third_party_id}, {category_id}),"
print_to_screen_cat = print_to_screen_cat[:-1]
print(print_to_screen_cat)
# TODO addresses