Afin que tout le monde réalise ce TD sur une application Flask sans erreurs et correctement configurée:
Tout type de base de données peut être branché à une application Flask grâce à des librairies externes de Python. Pour plus de facilités, une base relationnelle SQLite sera utilisée.
flask-sqlalchemy
dans l'environnement virtuel de l'applicationTout comme notre application est une instance de Flask, nommée app
, la connexion à la base de donnée sera une instance de SQLAlchemy, communément nommée db
. L'objet db
prend comme premier argument l'application Flask. Documentation de l'objet SQLAlchemy
app.py
, créer l'instance db
. Attention à bien positionner cette instanciation par rapport à l'instance app
et aux imports finaux des routes.Either 'SQLALCHEMY_DATABASE_URI' or 'SQLALCHEMY_BINDS' must be set.
doit apparaître.SQLALCHEMY_DATABASE_URI
SQLALCHEMY_DATABASE_URI
et sa valeur nécessitent une seule ligne dans un fichierdb
puisque db
est configurée avec app
) s'écrit en une seule ligne dans un fichier de configurationSQLALCHEMY_DATABASE_URI
sera le chemin vers la base de données . Ce chemin peut être absolu ou relatif, et varie selon les OS. Ecrire ce chemin selon la documentation* Running on http://127.0.0.1:5000
dans le terminalPour le moment, aucun rendu via un template HTML n'est demandé. On va se concentrer sur les retours dans le terminal. Le lancement de l'application sans erreurs est normalement gage de bonne connectivité avec la base de données SQLite. Néanmoins, il faut s'assurer que l'on puisse lire des données, sans utiliser pour le moment les fonctionnalités d'ORM de SQLAlchemy. On va donc simplement exécuter une requête SQL.
Voici le modèle de données de la base:
/pays
dans le module routes/generales
. Cette route est actuellement fonctionnelle et affiche des données écrites à la main dans le code.SELECT * FROM country LIMIT 10
db
de SQLAlchemy que l'on a configuré plus haut. Faire en sorte d'avoir accès à db
dans le module de la routeresultats
dans la route /pays
qui correspondent aux résultats de la requête: https://docs.sqlalchemy.org/en/20/orm/session_api.html#sqlalchemy.orm.Session.execute et Ticket StackOverFlowlocalhost:5000/pays
localhost:5000/pays
et l'affichage dans les logs de[("<p>Algeria has known many empires and dynasties starting with the ancient Numidians (3rd century B.C.), Phoenicians, Carthaginians, Romans, Vandals, ... (
2790 characters truncated) ... arbon revenues to fund the government and finance the large subsidies for the population has fallen under stress because of dec
lining oil prices.</p>", 'ag', 'Algeria', 'sovereign'), ("From the late 14th to the mid 19th century a Kingdom of Kongo stretched across central Africa from p
resent-day northern Angola into the current Congo ... (1141 characters truncated) ... He pushed through a new constitution in 2010. Joao LOURENCO was elected
president in August 2017 and became president of the MPLA in September 2018.", 'ao', 'Angola', 'sovereign'), ('Seeking to stop the incorporation of their lan
d into Rhodesia (Zimbabwe) or the Union of South Africa, in 1885, three tribal chiefs traveled to Great ... (965 characters truncated) ... the world\'s highes
t rates of HIV/AIDS infection, but also one of Africa\'s most progressive and comprehensive programs for dealing with the disease.', 'bc', 'Botswana', 'sovere
ign'), ('Present day Benin is comprised of about 42 ethnic groups, including the Yoruba in the southeast, who migrated from what is now Nigeria in the 12th ce
... (1657 characters truncated) ... k office in 2016; the space for pluralism, dissent, and free expression has narrowed under his administration. TALON won
a second term in April 2021.', 'bn', 'Benin', 'sovereign'), ("<p>Established in the 1600s, the Burundi Kingdom has had borders similar to those of modern Buru
ndi since the 1800s. Burundi’s two major ethnic group ... (2274 characters truncated) ... al court decision allowed him to circumvent a term limit. President
Evariste NDAYISHIMIYE - from NKURUNZIZA’s ruling party - was elected in 2020.</p>", 'by', 'Burundi', 'sovereign'), ('<p>Chad emerged from a collection of powe
rful states that controlled the Sahelian belt starting around the 9th century. These states focused on contr ... (3028 characters truncated) ... Chadian mili
tary camp in the Lake Chad Basin and killed nearly 100 soldiers; it was the deadliest attack in the history of the Chadian military.</p>', 'cd', 'Chad', 'sove
reign'), ("Upon independence in 1960, the former French region of Middle Congo became the Republic of the Congo. A quarter century of experimentation with Mar
xi ... (821 characters truncated) ... rica's largest petroleum producers, but with declining production it will need new offshore oil finds to sustain its oil
earnings over the long term.", 'cf', 'Congo', 'sovereign'), ("<p>The Kingdom of Kongo ruled the area around the mouth of the Congo River from the 14th to 19t
h centuries. To the center and east, the Kingdoms of L ... (3506 characters truncated) ... n the DRC (MONUSCO) has operated in the region since 1999 and is th
e largest and most expensive UN peacekeeping mission in the world.</p> <p>\xa0</p>", 'cg', 'Congo DR', 'sovereign'), ('Much of the area of present-day Cameroo
n was ruled by powerful chiefdoms before becoming a German colony in 1884 known as Kamerun. After World War I, ... (528 characters truncated) ... as well as
a petroleum industry. Despite slow movement toward democratic reform, political power remains firmly in the hands of President Paul BIYA.', 'cm', 'Cameroon',
'sovereign'), ("The archipelago of the Comoros in the Indian Ocean, composed of the islands of Mayotte, Anjouan, Moheli, and Grande Comore declared independen
ce from ... (1789 characters truncated) ... between the three main islands. In August 2018, President AZALI formed a new government and subsequently ran and w
as elected president in March 2019.", 'cn', 'Comoros', 'sovereign')]
Plutôt que d'effectuer des requêtes SQL à la main, l'ORM propose de les générer à notre place. Pour cela, il est nécessaire d'indiquer à l'ORM une représentation de nos données. Les données conservées en base sont alors représentées en une collection d'objets (de classes), ce qui est nommé modèles de base de données. La couche ORM va alors effectuer le mapping modèle>table elle-même.
Chaque table est représentée par un modèle, qui est lui-même une classe Python dérivée de SQLAlchemy(app).Model qui porte le même nom que la table (l'ORM est insensible à la casse pour le nom de table; par convention, il est préférable de nommer chaque classe en camelCase). Les modèles sont stockés dans un au plusieurs fichiers Python dans le package models. Chaque attribut de la classe représente une colonne de la table.
De manière théorique, les classes représentant les tables s'écrivent ainsi (ce qui est entre <<>> est spécifique à la table décrite):
class <<objectName>>(db.Model):
<<colonne1>> = db.Column(db.<<objectType>>)
<<colonne2>> = db.Column(db.<<objectType>>)
...
models
, à côté des packages routes
ou templates
déjà existantsfactbook
dans le package models
routes/generales
Maintenant que la base de données est branchée et qu'un premier objet Country représente une des tables de la base, on va pouvoir brancher la base de données à la route /pays
. Le but des étapes suivantes est de ne pas avoir à toucher aux templates, seulement à la fonction pays()
: autrement dit, il s'agit simplement de renvoyer au template des données au format demandé
[{
"nom":"string",
"capitale":"string",
"continent":"string"
}]
à partir des résultats d'une requête faite par l'ORM à la base de données.
SELECT * FROM Country
en SQLAlchemy à partir de la classe Country : https://flask-sqlalchemy.palletsprojects.com/en/2.x/queries/. Plusieurs méthodes sont possibles; toutes doivent renvoyer une liste d'objets qui représentent les pays : [<Country ag>, <Country ao>, <Country bc>, <Country bn>, <Country by>, <Country cd>, <Country cf>, <Country cg>, ..., <Country par>]
<Country par>
<class 'app.models.factbook.Country'>
xx
World
donnees
contient des données écrites en dur. Remplir cette variable avec les données requises de chaque pays pour qu'elles s'affichent dans le template (sans toucher à celui-ci):
/pays
. Les pays doivent s'afficher en tableau.