"Ce notebook est une première ébacuhe pour tester ce qu'il est possible de faire pour apprendre les bases de données relationnelles en utilisant des notebooks Jupyter."
]
},
{
"cell_type": "markdown",
"id": "106e64f2-2480-406a-9a8b-69759603c37a",
"metadata": {},
"source": [
"## Modélisation \n",
"\n",
"### MEA\n",
"Un MEA peut etre réalisé simplement avec [MoCoDo](https://rawgit.com/laowantong/mocodo/master/doc/fr_refman.html).\n",
"Cet outils permet entre autres de générer à partir d'une description textuelle, le schéma, le passage vers le modèle relationnel (relations, diagramme des tables et script de création)."
"link Commande to apoint7--><pathd=\"M127.41,207C167.38,207214.42,207225.55,207\"fill=\"none\"id=\"Commande-apoint7\"style=\"stroke:#A80036;stroke-width:1.0;\"/><textfill=\"#000000\"font-family=\"sans-serif\"font-size=\"13\"lengthAdjust=\"spacing\"textLength=\"62\"x=\"145.5\"y=\"200.0669\">comporte</text><textfill=\"#000000\"font-family=\"sans-serif\"font-size=\"13\"lengthAdjust=\"spacing\"textLength=\"7\"x=\"135.199\"y=\"203.1847\">*</text><!--MD5=[a25ac98b4e49c86dcf5b35d8b1abc2f0]\n",
"link apoint7 to Produit--><pathd=\"M230.11,207C240.09,207250.07,207260.05,207\"fill=\"none\"id=\"apoint7-to-Produit\"style=\"stroke:#A80036;stroke-width:1.0;\"/><polygonfill=\"#A80036\"points=\"265.27,207,256.27,203,260.27,207,256.27,211,265.27,207\"style=\"stroke:#A80036;stroke-width:1.0;\"/><textfill=\"#000000\"font-family=\"sans-serif\"font-size=\"13\"lengthAdjust=\"spacing\"textLength=\"23\"x=\"237.9629\"y=\"201.7777\">1..*</text><!--MD5=[f38a02434c5678a2e9ce26b6952cd29d]\n",
"link apoint7 to LigneDeCommande--><pathd=\"M228,209.42C228,218.65228,270.78228,304.76\"fill=\"none\"id=\"apoint7-LigneDeCommande\"style=\"stroke:#A80036;stroke-width:1.0;stroke-dasharray:7.0,7.0;\"/><!--MD5=[f72067e05319408abc0251939a098f2a]\n",
"link Client to Commande--><pathcodeLine=\"21\"d=\"M67,93.35C67,117.2967,146.8967,169.75\"fill=\"none\"id=\"Client-Commande\"style=\"stroke:#A80036;stroke-width:1.0;\"/><textfill=\"#000000\"font-family=\"sans-serif\"font-size=\"13\"lengthAdjust=\"spacing\"textLength=\"38\"x=\"68\"y=\"136.0669\">passe</text><textfill=\"#000000\"font-family=\"sans-serif\"font-size=\"13\"lengthAdjust=\"spacing\"textLength=\"8\"x=\"58.3625\"y=\"113.4987\">1</text><textfill=\"#000000\"font-family=\"sans-serif\"font-size=\"13\"lengthAdjust=\"spacing\"textLength=\"7\"x=\"59.3766\"y=\"158.8924\">*</text><!--MD5=[03c01ea5f2545a2a8d79bab17a9db863]\n",
"@startuml\n",
"class Commande { \n",
" - numero : Integer\n",
" - date : Date \n",
" }\n",
"class Produit {\n",
" - code : Integer\n",
" - prixUnitaire : Integer\n",
" }\n",
"class LigneDeCommande { \n",
" - quantité : Integer \n",
" } \n",
"\n",
"class Client { \n",
" - email : String \n",
" - nom : String \n",
" - prenom : String \n",
" }\n",
"\n",
"Commande \"*\" -> \"1..*\" Produit : comporte\n",
"(Commande, Produit) .. LigneDeCommande\n",
"Client \"1\" - - \"*\" Commande : passe\n",
"@enduml\n",
"\n",
"PlantUML version 1.2021.12(Tue Oct 05 16:01:58 UTC 2021)\n",
"(GPL source distribution)\n",
"Java Runtime: OpenJDK Runtime Environment\n",
"JVM: OpenJDK 64-Bit Server VM\n",
"Default Encoding: UTF-8\n",
"Language: en\n",
"Country: US\n",
"--></g></svg>"
],
"text/plain": [
"<IPython.core.display.SVGobject>"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%plantuml --jar\n",
"@startuml\n",
"class Commande { \n",
" - numero : Integer\n",
" - date : Date \n",
" }\n",
"class Produit {\n",
" - code : Integer\n",
" - prixUnitaire : Integer\n",
" }\n",
"class LigneDeCommande { \n",
" - quantité : Integer \n",
" } \n",
"\n",
"class Client { \n",
" - email : String \n",
" - nom : String \n",
" - prenom : String \n",
" }\n",
"\n",
"Commande \"*\" -> \"1..*\" Produit : comporte\n",
"(Commande, Produit) .. LigneDeCommande\n",
"Client \"1\" -- \"*\" Commande : passe\n",
"@enduml"
]
},
{
"cell_type": "markdown",
"id": "8faa6c8f-3be8-4fa4-9675-c3f2f354adfb",
"metadata": {},
"source": [
"## Initialisation connection SGBD\n",
"L'intégration de SQL est faite avec [ipython-sql](https://github.com/catherinedevlin/ipython-sql).\n",
"\n",
"\n",
"Pour commencer, il faut changer l'extension SQL pour jupyter."
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "ca072ea3-2f43-4542-a7ba-2d4921ca152f",
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"%reload_ext sql"
]
},
{
"cell_type": "markdown",
"id": "5427ddce-56ea-461b-ac29-e4864b97ce8b",
"metadata": {},
"source": [
"Le lancement du serveur PostgreSQL et création d'une base de données est automatique avant le lancement dans le répertoire 'work/pgdata/DEMO_DB'.\n",
"\n",
"L'ouverture d'une connexion à la base de données peut se faire une seule fois ou à chaque requête (il est possible d'avoir plusieurs connections différentes)."
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "cfbca6ff-1393-43da-aa4c-16869fa6f8e0",
"metadata": {},
"outputs": [],
"source": [
"%sql postgresql://localhost/jovyandb"
]
},
{
"cell_type": "markdown",
"id": "497856bb-827f-4b5c-9479-7a76b1fb4919",
"metadata": {},
"source": [
"## Utilisation de SQL\n",
"L'utilisation SQL peut se faire dans une cellule en le préfixant de %%sql"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "2c918a0c-5a0f-4db0-b76a-6ae37d13589a",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" * postgresql://localhost/jovyandb\n",
"Done.\n",
"Done.\n",
"Done.\n",
"Done.\n",
"Done.\n",
"Done.\n",
"Done.\n",
"Done.\n"
]
},
{
"data": {
"text/plain": [
"[]"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%sql\n",
"DROP TABLE IF EXISTS LIGNE_DE_COMMANDE;\n",
"DROP TABLE IF EXISTS COMMANDE;\n",
"DROP TABLE IF EXISTS CLIENT;\n",
"DROP TABLE IF EXISTS PRODUIT;\n",
"\n",
"CREATE TABLE CLIENT (\n",
" id_client int GENERATED ALWAYS AS IDENTITY,\n",
" email varchar(255) NOT NULL UNIQUE,\n",
" nom varchar(100) NOT NULL,\n",
" prenom varchar(100) NOT NULL,\n",
" PRIMARY KEY(id_client) \n",
");\n",
"\n",
"CREATE TABLE PRODUIT (\n",
" code_produit int GENERATED ALWAYS AS IDENTITY,\n",
" description varchar(10),\n",
" prix_unitaire int,\n",
" PRIMARY KEY(code_produit)\n",
");\n",
" \n",
"CREATE TABLE COMMANDE (\n",
" numero_commande int GENERATED ALWAYS AS IDENTITY, \n",
" date date DEFAULT CURRENT_DATE,\n",
" id_client int,\n",
" PRIMARY KEY(numero_commande),\n",
" CONSTRAINT fk_client\n",
" FOREIGN KEY(id_client) \n",
" REFERENCES CLIENT(id_client)\n",
");\n",
"\n",
"CREATE TABLE LIGNE_DE_COMMANDE (\n",
" numero_commande int,\n",
" code_produit int,\n",
" quantite int,\n",
" PRIMARY KEY(numero_commande, code_produit)\n",
");"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "e3b35f69-a5eb-4888-b518-84f3a0841fba",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" * postgresql://localhost/jovyandb\n",
"1 rows affected.\n",
"1 rows affected.\n",
"1 rows affected.\n"
]
},
{
"data": {
"text/plain": [
"[]"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%sql\n",
"INSERT INTO CLIENT (email, nom, prenom) VALUES ('a.b@x.fr','a','b');\n",
"INSERT INTO CLIENT (email, nom, prenom) VALUES ('c.d@x.fr','c','d');\n",
"INSERT INTO CLIENT (email, nom, prenom) VALUES ('e.f@x.fr','e','f');"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "9232e8ad-c21e-4bf1-b92d-30be7ec5d94a",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" * postgresql://localhost/jovyandb\n",
"3 rows affected.\n"
]
},
{
"data": {
"text/html": [
"<table>\n",
" <tr>\n",
" <th>id_client</th>\n",
" <th>email</th>\n",
" <th>nom</th>\n",
" <th>prenom</th>\n",
" </tr>\n",
" <tr>\n",
" <td>1</td>\n",
" <td>a.b@x.fr</td>\n",
" <td>a</td>\n",
" <td>b</td>\n",
" </tr>\n",
" <tr>\n",
" <td>2</td>\n",
" <td>c.d@x.fr</td>\n",
" <td>c</td>\n",
" <td>d</td>\n",
" </tr>\n",
" <tr>\n",
" <td>3</td>\n",
" <td>e.f@x.fr</td>\n",
" <td>e</td>\n",
" <td>f</td>\n",
" </tr>\n",
"</table>"
],
"text/plain": [
"[(1, 'a.b@x.fr', 'a', 'b'),\n",
" (2, 'c.d@x.fr', 'c', 'd'),\n",
" (3, 'e.f@x.fr', 'e', 'f')]"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%sql \n",
"SELECT * FROM CLIENT"
]
},
{
"cell_type": "markdown",
"id": "e9130678-99f7-42c0-a474-aabfbfc8f355",
"metadata": {},
"source": [
"Les résultats des requêtes peuvent être affecté dans des variables python et traitée sous forme de dataframes avec la librairie Panda."
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "c0e8873f-6c46-455d-829d-d042770d9e08",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" * postgresql://localhost/jovyandb\n",
"3 rows affected.\n",
"<class'pandas.core.frame.DataFrame'>\n",
"RangeIndex: 3 entries, 0 to 2\n",
"Data columns (total 4 columns):\n",
" # Column Non-Null Count Dtype \n",
"--- ------ -------------- ----- \n",
" 0 id_client 3 non-null int64 \n",
" 1 email 3 non-null object\n",
" 2 nom 3 non-null object\n",
" 3 prenom 3 non-null object\n",
"dtypes: int64(1), object(3)\n",
"memory usage: 224.0+ bytes\n"
]
}
],
"source": [
"clients = %sql SELECT * FROM CLIENT\n",
"clients.DataFrame().info()"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "cc525ac0-15e4-4ef8-a16b-cad00ce948e3",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" * postgresql://localhost/jovyandb\n",
"1 rows affected.\n",
"1 rows affected.\n",
"1 rows affected.\n"
]
},
{
"data": {
"text/plain": [
"[]"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%%sql\n",
"INSERT INTO PRODUIT (description, prix_unitaire) VALUES ('pomme',2);\n",
"INSERT INTO PRODUIT (description, prix_unitaire) VALUES ('peche',4);\n",
"INSERT INTO PRODUIT (description, prix_unitaire) VALUES ('poire',3);"
Ce notebook est une première ébacuhe pour tester ce qu'il est possible de faire pour apprendre les bases de données relationnelles en utilisant des notebooks Jupyter.
Un MEA peut etre réalisé simplement avec [MoCoDo](https://rawgit.com/laowantong/mocodo/master/doc/fr_refman.html).
Cet outils permet entre autres de générer à partir d'une description textuelle, le schéma, le passage vers le modèle relationnel (relations, diagramme des tables et script de création).
Le lancement du serveur PostgreSQL et création d'une base de données est automatique avant le lancement dans le répertoire 'work/pgdata/DEMO_DB'.
L'ouverture d'une connexion à la base de données peut se faire une seule fois ou à chaque requête (il est possible d'avoir plusieurs connections différentes).