<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet title="XSL formatting" type="text/xsl" href="http://blog.netapsys.fr/index.php/feed/rss2/xslt" ?><rss version="2.0"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:wfw="http://wellformedweb.org/CommentAPI/"
  xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel>
  <title>Netapsys Blog</title>
  <link>http://blog.netapsys.fr/index.php/</link>
  <description></description>
  <language>fr</language>
  <pubDate>Thu, 29 Jul 2010 16:33:35 +0200</pubDate>
  <copyright>Netapsys 2008 - 2009</copyright>
  <docs>http://blogs.law.harvard.edu/tech/rss</docs>
  <generator>Dotclear</generator>
  
    
  <item>
    <title>Intégrité référentielle et utilisation de fonctions SQL, ou comment rendre au SGBD une partie de ses responsabilités.</title>
    <link>http://blog.netapsys.fr/index.php/post/2009/03/12/Integrite-referentielle-et-utilisation-de-fonctions-SQL-ou-comment-rendre-au-SGBD-une-partie-de-ses-responsabilites</link>
    <guid isPermaLink="false">urn:md5:87d2b7598160a6d97c7d2f2dc8cc49a6</guid>
    <pubDate>Thu, 12 Mar 2009 18:03:00 +0100</pubDate>
    <dc:creator>Darko Stankovski</dc:creator>
        <category>SQL</category>
        <category>clé primaire</category><category>clé étrangère</category><category>contrainte intégrité</category><category>ifnull</category><category>intégrité référentielle</category><category>nvl</category><category>sql</category><category>tutoriel</category>    
    <description>&lt;p&gt;Faisons suite au dernier billet de Céline en restant dans le domaine des bases de données et des petites astuces connues de tous mais jamais utilisées. Intéressons nous à la gestion de l'intégrité référentielle et au calcul d'identifiants en laissant la base faire ce qu'elle sait faire et éviter un développement applicatif inutile.&lt;/p&gt;    &lt;h3&gt;Contexte&lt;/h3&gt;


&lt;p&gt;Posons l'exemple. Soit donc une base avec les tables suivantes&amp;nbsp;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Categorie (id, libelle)&lt;/li&gt;
&lt;li&gt;SousCategorie (idCategorie, id, libelle)&lt;/li&gt;
&lt;li&gt;Employe (id, idSousCategorie, nom).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ah ces chers employés... Nous allons donc catégoriser les employés en catégorie et sous-catégorie ou pas. Une sous catégorie est donc automatiquement associée à une catégorie et un employé peut ou non être associé à une sous-catégorie. La clef primaire de chaque table est évidente. Mais on va compliquer un peu et définir que pour les sous-catégories, l'Id est relatif à la catégorie et n'est donc pas unique. Par contre, le couple est unique. Les champs &lt;strong&gt;Id&lt;/strong&gt; seront donc les clefs primaires pour les tables &lt;em&gt;Categorie&lt;/em&gt; et &lt;em&gt;Employe&lt;/em&gt; et la table &lt;em&gt;SousCategorie&lt;/em&gt; aura une clef composite &lt;strong&gt;idCategorie, id&lt;/strong&gt;.&lt;/p&gt;


&lt;p&gt;Évidemment, il faut ensuite poser les clefs étrangères. Sur ce modèle &quot;simple&quot;, elles sont claires&amp;nbsp;: &lt;em&gt;idSousCategorie&lt;/em&gt; d&lt;em&gt;'Employe&lt;/em&gt; référence &lt;em&gt;id&lt;/em&gt; de &lt;em&gt;SousCategorie&lt;/em&gt; et &lt;em&gt;idCategorie&lt;/em&gt; de &lt;em&gt;SousCategorie&lt;/em&gt; référence &lt;em&gt;id&lt;/em&gt; de &lt;em&gt;Categorie&lt;/em&gt;. Allons-y pour la création classique des tables sous MySql.&lt;/p&gt;

&lt;pre class=&quot;sql&quot;&gt;&lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;CREATE&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;TABLE&lt;/span&gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;`categorie`&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;
    &lt;span style=&quot;color: #ff0000;&quot;&gt;`id`&lt;/span&gt; INT &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NOT&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NULL&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;AUTO_INCREMENT&lt;/span&gt;,
    &lt;span style=&quot;color: #ff0000;&quot;&gt;`libelle`&lt;/span&gt;VARCHAR&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #cc66cc;&quot;&gt;30&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NOT&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NULL&lt;/span&gt;,
    &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;PRIMARY&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;KEY&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;id&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; ENGIN&lt;span style=&quot;color: #66cc66;&quot;&gt;=&lt;/span&gt;InnoDB;
&amp;nbsp;
&lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;CREATE&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;TABLE&lt;/span&gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;`souscategorie`&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;
    &lt;span style=&quot;color: #ff0000;&quot;&gt;`idcategorie`&lt;/span&gt; INT &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NOT&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NULL&lt;/span&gt;,
    &lt;span style=&quot;color: #ff0000;&quot;&gt;`id`&lt;/span&gt; INT &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NOT&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NULL&lt;/span&gt;,
    &lt;span style=&quot;color: #ff0000;&quot;&gt;`libelle`&lt;/span&gt;VARCHAR&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #cc66cc;&quot;&gt;30&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NOT&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NULL&lt;/span&gt;,
    &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;PRIMARY&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;KEY&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;idcategorie, id&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;,
    CONSTRAINT &lt;span style=&quot;color: #ff0000;&quot;&gt;`FK_SOUSCATEGORIE`&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;FOREIGN&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;KEY&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;idcategorie&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
        &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;REFERENCES&lt;/span&gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;`categorie`&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;`id`&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; ENGIN&lt;span style=&quot;color: #66cc66;&quot;&gt;=&lt;/span&gt;InnoDB;
&amp;nbsp;
&lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;CREATE&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;TABLE&lt;/span&gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;`employe`&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;
    &lt;span style=&quot;color: #ff0000;&quot;&gt;`id`&lt;/span&gt; INT &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NOT&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NULL&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;AUTO_INCREMENT&lt;/span&gt;,
    &lt;span style=&quot;color: #ff0000;&quot;&gt;`idsouscategorie`&lt;/span&gt;INT &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;DEFAULT&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NULL&lt;/span&gt;,
    &lt;span style=&quot;color: #ff0000;&quot;&gt;`nom`&lt;/span&gt;VARCHAR&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #cc66cc;&quot;&gt;40&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NOT&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NULL&lt;/span&gt;,
    &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;PRIMARY&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;KEY&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;id&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;,
    CONSTRAINT &lt;span style=&quot;color: #ff0000;&quot;&gt;`FK_EMPLOYE`&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;FOREIGN&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;KEY&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;idsouscategorie&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
        &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;REFERENCES&lt;/span&gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;`souscategorie`&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;`id`&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; ENGIN&lt;span style=&quot;color: #66cc66;&quot;&gt;=&lt;/span&gt;InnoDB;&lt;/pre&gt;


&lt;p&gt;Voilà. Incroyable et révolutionnaire. Bon, maintenant, regardons un peu la logique de traitement. On peut ajouter des catégories. On peut ajouter des sous-catégories à une catégorie existante. On peut créer un employé, et on peut affecter un employé à une sous-catégorie. Dans le même ordre d'idée, on peut supprimer un employé, une sous-catégorie si aucun employé ne lui est affecté, et une catégorie si elle ne possède pas de sous catégorie.&lt;/p&gt;


&lt;p&gt;Lors de la gestion des projets mettant en jeu une base qui ressemblerait à ça et l'applicatif qui va avec, on voit souvent la conception de la base s'arrêter là et les traitements remonter au niveau de l'applicatif. Ainsi, la fonctionnalité de suppression d'une catégorie supprimera toutes les sous-catégories avant de supprimer la catégorie. Fonctionnellement c'est correct, mais que d'énergie dépensée pour pas grand chose. Surtout si les règles sont que pour toute suppression de catégorie, les sous-catégories doivent être simplement supprimées et pour toute suppression de sous-catégorie, les employés doivent simplement en être désaffectés.&lt;/p&gt;


&lt;h3&gt;Gestion de l'intégrité référentielle&lt;/h3&gt;

&lt;p&gt;Les bases de données sont capables de gérer leur intégrité référentielle. Il suffit pour ça de rajouter une clause &lt;strong&gt;ON DELETE&lt;/strong&gt; aux contraintes de clef étrangère.&lt;/p&gt;


&lt;h4&gt;Cas de la suppression d'une sous-catégorie&lt;/h4&gt;

&lt;p&gt;Une sous-catégorie ne peut être supprimée que si aucun employé ne lui est affecté (contrainte &lt;em&gt;FK_EMPLOYE&lt;/em&gt;). Supprimer une sous-catégorie ne doit entraîner que la désaffectation de l'employé de ladite catégorie. Il suffit alors d'utiliser la clause &lt;strong&gt;ON DELETE SET NULL&lt;/strong&gt;. Ainsi lors de la suppression d'une sous-catégorie, tous les employés affectés à cette sous-catégorie verront leur champ &lt;em&gt;idsouscategorie&lt;/em&gt; modifié en &lt;em&gt;NULL&lt;/em&gt;. Le code pour créer cette table sera maintenant&amp;nbsp;:&lt;/p&gt;

&lt;pre class=&quot;sql&quot;&gt;&lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;CREATE&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;TABLE&lt;/span&gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;`employe`&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;
    &lt;span style=&quot;color: #ff0000;&quot;&gt;`id`&lt;/span&gt; INT &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NOT&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NULL&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;AUTO_INCREMENT&lt;/span&gt;,
    &lt;span style=&quot;color: #ff0000;&quot;&gt;`idsouscategorie`&lt;/span&gt;INT &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;DEFAULT&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NULL&lt;/span&gt;,
    &lt;span style=&quot;color: #ff0000;&quot;&gt;`nom`&lt;/span&gt;VARCHAR&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #cc66cc;&quot;&gt;40&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NOT&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NULL&lt;/span&gt;,
    &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;PRIMARY&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;KEY&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;id&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;,
    CONSTRAINT &lt;span style=&quot;color: #ff0000;&quot;&gt;`FK_EMPLOYE`&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;FOREIGN&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;KEY&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;idsouscategorie&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
        &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;REFERENCES&lt;/span&gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;`souscategorie`&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;`id`&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
        &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;ON&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;DELETE&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;SET&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NULL&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; ENGIN&lt;span style=&quot;color: #66cc66;&quot;&gt;=&lt;/span&gt;InnoDB;&lt;/pre&gt;



&lt;h4&gt;Cas de la suppression d'une catégorie&lt;/h4&gt;

&lt;p&gt;Une catégorie ne peut être supprimée que si aucune sous-catégorie ne lui est affectée (contrainte &lt;em&gt;FK_SOUSCATEGORIE&lt;/em&gt;). Contrairement à l'employé, une sous-catégorie n'a aucun sens à elle toute seule. Ce coup-ci, il faudra utiliser la clause &lt;strong&gt;ON DELETE CASCADE&lt;/strong&gt;. Ainsi, pour la suppression d'une catégorie, la base supprimera toutes les sous-catégories s'y référant. Le code pour créer cette table sera maintenant&amp;nbsp;:&lt;/p&gt;

&lt;pre class=&quot;sql&quot;&gt;&lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;CREATE&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;TABLE&lt;/span&gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;`souscategorie`&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;
    &lt;span style=&quot;color: #ff0000;&quot;&gt;`idcategorie`&lt;/span&gt; INT &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NOT&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NULL&lt;/span&gt;,
    &lt;span style=&quot;color: #ff0000;&quot;&gt;`id`&lt;/span&gt; INT &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NOT&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NULL&lt;/span&gt;,
    &lt;span style=&quot;color: #ff0000;&quot;&gt;`libelle`&lt;/span&gt;VARCHAR&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #cc66cc;&quot;&gt;30&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NOT&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;NULL&lt;/span&gt;,
    &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;PRIMARY&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;KEY&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;idcategorie, id&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;,
    CONSTRAINT &lt;span style=&quot;color: #ff0000;&quot;&gt;`FK_SOUSCATEGORIE`&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;FOREIGN&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;KEY&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;idcategorie&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
        &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;REFERENCES&lt;/span&gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;`categorie`&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;`id`&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
        &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;ON&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;DELETE&lt;/span&gt; CASCADE&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; ENGIN&lt;span style=&quot;color: #66cc66;&quot;&gt;=&lt;/span&gt;InnoDB;&lt;/pre&gt;


&lt;p&gt;Ainsi, l'intégrité référentielle des données est toujours respectée quel que soit le contexte et est indépendante d'un applicatif. Supprimer une catégorie supprimera les sous-catégories affectées et la suppression d'une sous-catégorie désaffectera les employés affectés. En conséquence, le développement de l'applicatif n'est que facilité. Chaque entité a des responsabilités dédiées et limitées, avec comme conséquence la plus importante, le fait que quelle que soit l'action sur la base, l'intégrité référentielle est toujours respectée.&lt;/p&gt;


&lt;h3&gt;Ajout de sous-catégories&lt;/h3&gt;

&lt;p&gt;Revenons à nos sous-catégories. En ce qui les concerne, la clef primaire est une clef composite. Il est impossible d'utiliser des instructions comme &lt;em&gt;AUTO_INCREMENT&lt;/em&gt; car l'id de la sous-catégorie doit être relatif à la catégorie (catégorie 1, sous catégorie 1&amp;nbsp;; catégorie 1, sous catégorie 2&amp;nbsp;; catégorie 1, sous catégorie 3&amp;nbsp;; catégorie 2, sous catégorie 1&amp;nbsp;; catégorie 2, sous catégorie 2). Ne demandez pas pourquoi, c'est comme ça. Il faudra donc affecter les données à la main. Il est évident qu'il faudra récupérer l'id de la catégorie avant de faire une insertion. Quand à l'affectation de l'identifiant de la sous-catégorie, on peut utiliser la requête (écrite sous la forme d'une requête paramétrée Java)&amp;nbsp;:&lt;/p&gt;

&lt;pre class=&quot;sql&quot;&gt;&lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;SELECT&lt;/span&gt; MAX&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;id&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;FROM&lt;/span&gt; souscategorie &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;WHERE&lt;/span&gt; idcategorie &lt;span style=&quot;color: #66cc66;&quot;&gt;=&lt;/span&gt; ?&lt;/pre&gt;


&lt;p&gt;ce qui fait que nous pouvons proposer la requête suivante pour une insertion&amp;nbsp;:&lt;/p&gt;

&lt;pre class=&quot;sql&quot;&gt;&lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;INSERT&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;INTO&lt;/span&gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;`souscategorie`&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;`idcategorie`&lt;/span&gt;, &lt;span style=&quot;color: #ff0000;&quot;&gt;`id`&lt;/span&gt;, &lt;span style=&quot;color: #ff0000;&quot;&gt;`libelle`&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;VALUES&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;?, &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;SELECT&lt;/span&gt; MAX&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;id&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;FROM&lt;/span&gt; souscategorie &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;WHERE&lt;/span&gt; idcategorie &lt;span style=&quot;color: #66cc66;&quot;&gt;=&lt;/span&gt; ?&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; + &lt;span style=&quot;color: #cc66cc;&quot;&gt;1&lt;/span&gt;, ?&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/pre&gt;


&lt;p&gt;Sauf qu'il y a des cas où cette requête ne marche pas... S'il s'agit d'ajouter une sous-catégorie à une catégorie qui n'a pas encore de sous-catégorie, le &lt;em&gt;SELECT&lt;/em&gt; rend un beau &lt;em&gt;NULL&lt;/em&gt;. Aie...&lt;/p&gt;


&lt;p&gt;Alors évidemment, on peut laisser l'applicatif gérer le &lt;em&gt;select&lt;/em&gt; et agir en fonction, mais cela alourdit le code applicatif et provoque deux appels à la base. On peut aussi utiliser certaines fonctions SQL propres à la base pour réaliser cette action. Ici, nous utiliserons la fonction &lt;strong&gt;IFNULL&lt;/strong&gt;. La signature de cette fonction est &lt;em&gt;IFNULL(expr1, expr2)&lt;/em&gt;. Si &lt;em&gt;expr1&lt;/em&gt; n'est pas &lt;em&gt;null&lt;/em&gt;, &lt;em&gt;IFNULL&lt;/em&gt; renvoi &lt;em&gt;expr1&lt;/em&gt;, sinon elle renvoie &lt;em&gt;expr2&lt;/em&gt;. Et bien voila notre solution&amp;nbsp;:&lt;/p&gt;

&lt;pre class=&quot;sql&quot;&gt;&lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;INSERT&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;INTO&lt;/span&gt; &lt;span style=&quot;color: #ff0000;&quot;&gt;`souscategorie`&lt;/span&gt; &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff0000;&quot;&gt;`idcategorie`&lt;/span&gt;, &lt;span style=&quot;color: #ff0000;&quot;&gt;`id`&lt;/span&gt;, &lt;span style=&quot;color: #ff0000;&quot;&gt;`libelle`&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;VALUES&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;?, &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;IFNULL&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;SELECT&lt;/span&gt; MAX&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#40;&lt;/span&gt;id&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;FROM&lt;/span&gt; souscategorie &lt;span style=&quot;color: #993333; font-weight: bold;&quot;&gt;WHERE&lt;/span&gt; idcategorie &lt;span style=&quot;color: #66cc66;&quot;&gt;=&lt;/span&gt; ?&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;, &lt;span style=&quot;color: #cc66cc;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt; + &lt;span style=&quot;color: #cc66cc;&quot;&gt;1&lt;/span&gt;, ?&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;#41;&lt;/span&gt;;&lt;/pre&gt;


&lt;p&gt;Dans ce cas, s'il n'y a pas encore de sous-catégorie pour la catégorie voulue (le &lt;em&gt;select&lt;/em&gt; renvoi &lt;em&gt;null&lt;/em&gt;), la fonction &lt;em&gt;IFNULL&lt;/em&gt; renverra 0 et nous aurons notre premier identifiant qui vaudra 1.&lt;/p&gt;


&lt;p&gt;A noter que &lt;strong&gt;IFNULL&lt;/strong&gt; est spécifique à MySQL. Sous Oracle ou Informix, il s'agit de la fonction &lt;strong&gt;NVL&lt;/strong&gt;.&lt;/p&gt;


&lt;h3&gt;En conclusion&lt;/h3&gt;

&lt;p&gt;Il n'y a aucune haute voltige dans ce qui est présenté ici. Malheureusement, ce sont des situations souvent observées dans beaucoup de projets de gestion. Dans ce domaine, tout projet fait intervenir un applicatif et une base de données. Mais on observe bien souvent que le développement de la base de données se limite à définir les tables, leurs clefs primaires, leurs clefs étrangères et leurs indexs. Dans ces contextes, les contraintes d'intégrité référentielle sont gérées au niveau applicatif. La conséquence est évidente aussi bien en terme d'intégrité des données qui ne peut être assurée en fonction du type d'intervention, mais potentiellement en terme de coût de développement. Les SGBD sont aujourd'hui assez riches pour s'occuper aussi bien du stockage des données que d'assurer leur qualité. Lors du design de vos bases, n'hésitez pas à explorer les possibilités du SGBD.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.netapsys.fr/index.php/post/2009/03/12/Integrite-referentielle-et-utilisation-de-fonctions-SQL-ou-comment-rendre-au-SGBD-une-partie-de-ses-responsabilites#comment-form</comments>
      <wfw:comment>http://blog.netapsys.fr/index.php/post/2009/03/12/Integrite-referentielle-et-utilisation-de-fonctions-SQL-ou-comment-rendre-au-SGBD-une-partie-de-ses-responsabilites#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.netapsys.fr/index.php/feed/rss2/comments/77</wfw:commentRss>
      </item>
    
  <item>
    <title>Rigueur et sécurité</title>
    <link>http://blog.netapsys.fr/index.php/post/2009/01/14/Rigueur-et-securite</link>
    <guid isPermaLink="false">urn:md5:756692f0397861a2fb9b2e10026f37e3</guid>
    <pubDate>Wed, 04 Feb 2009 14:07:00 +0100</pubDate>
    <dc:creator>Darko Stankovski</dc:creator>
        <category>Bonnes pratiques</category>
            
    <description>&lt;p&gt;La nouvelle est abondamment relayée depuis sa parution. Le SANS Institute et MITRE Corporation ont publié le TOP 25 des erreurs de programmation pouvant provoquer de sérieux problèmes de sécurité. Cette liste a été élaborée conjointement entre différents organismes et sociétés impliquées dans le domaine de la sécurité informatique, et comporte les 25 erreurs les plus communément répertoriées. Ces erreurs concernent le développement web et les risques au niveau de la sécurité concernent aussi bien le côté serveur (donc l'applicatif et le fournisseur du service) que le côté client (concerne donc l'utilisateur du service). Les détails sont donnés en lien à la fin de l'article. Voyons par contre les tendances générales.&lt;/p&gt;    &lt;p&gt;De manière globale, ces erreurs sont qualifiables en trois types&amp;nbsp;: les connexions non sécurisées entre composants, la gestion risquée des ressources, et tout simplement la problématique de sécurité bâclée.&lt;/p&gt;


&lt;h3&gt;La communication entre composants&lt;/h3&gt;

&lt;p&gt;Cette catégorie regroupe toutes les insécurités liées à la communication entre composants, composants aussi bien propres à l'application (module, couches) qu'externes (appel à des programmes externes, communication avec une source de données, avec un client, un autre serveur...). La validation des données, ce grand classique et cas d'école par excellence, occupe encore la première place des trous de sécurité. Ce problème s'observe moins lorsque des frameworks sont utilisés, Struts est toujours pris en exemple (malgré des faiblesses et des mises en garde sur l'efficacité de la validation des données). Mais si la validation des formulaires est rentrée dans les habitudes, l'évolution des applications ouvre de nouvelles brèches car les données envoyées par webservices par exemple ne passeront pas par les validateurs de la couche de présentation web. Il est ainsi important d'avoir une bonne assurance de la validation des données.&lt;/p&gt;


&lt;p&gt;Cette notion de validation et de contrôle des données est ainsi la clef de voûte de la sécurité de la communication entre composants. De part sa nature, un système d'information va, en fonction d'entrées, exécuter des tâches ou récupérer des informations. Dans le développement web ou l'informatique de gestion, la base de données occupe une place importante. Il faut donc s'assurer du contrôle sur l'échange d'informations et donc que les requêtes ne pourront pas être altérées. Les propositions de protection insistent sur le fait qu'il faut éviter de construire soi-même dynamiquement les requêtes et préconisent l'utilisation de requêtes paramétrées. Figer les requêtes évite donc une restructuration de ces dernières. Cependant, cela n'est pas toujours possible, et il convient alors de masquer la construction des requêtes ce qui peut être facilement accompli en respectant la logique des couches. L'utilisation de l'API Criteria d'Hibernate, et celle de JPA de Java EE6 permet ainsi de garantir une sécurité contre l'injection SQL tout en permettant la création dynamique de requêtes.&lt;/p&gt;


&lt;p&gt;Il faut aussi noter qu'une base de données se paramètre et qu'il est possible de contrôler les accès et les actions par utilisateur et par table. De nombreux développements se concentrent sur une gestion de la sécurité au niveau applicatif et négligent totalement la configuration de la base de données. Votre profil &quot;visiteur&quot; qui n'a pas le droit de modifier les données, se connecte-t-il avec un utilisateur limité ou le même que le profil administrateur&amp;nbsp;?&lt;/p&gt;


&lt;p&gt;Dans le même ordre d'idées, une application, même web, peut faire appel à des applicatifs par des appels systèmes. Après tout, quoi de mieux que Graphviz pour générer des graphes, et en SVG dynamique s'il vous plaît&amp;nbsp;? Oui, mais s'il est mal implémenté, une attaque peut réaliser des exécutions malicieuses directement au niveau du système. La vigilance est semblable à celle de l'intégrité des requêtes SQL&amp;nbsp;: cacher les exécutions, et en limiter la portée.&lt;/p&gt;


&lt;p&gt;Enfin, le vieil adage du &quot;vivons heureux, vivons cachés&quot; se doit d'être respecté dans le développement d'applications ouvertes ainsi vers le web. Il arrive ainsi encore trop fréquemment que des informations sensibles transitent en clair, voir s'affichent dans les paramètres de requêtes. Combien d'applications ne font qu'un contrôle sommaire de connexion, puis ne se basent pour l'accès aux données que sur l'identifiant de l'utilisateur&amp;nbsp;? Identifiant passé en paramètre de la requête et modifiable à souhaits, évidemment...&lt;/p&gt;


&lt;p&gt;Dans le même ordre d'idées, il est bien connu que les serveurs de production doivent être configurer de manière à être le moins loquaces possible. Il doit en être de même pour les applications, surtout lors de la gestion des erreurs. En production, les informations sur les plantages et erreurs, si pratiques affichées à l'écran, ont plus leur place dans des logs.&lt;/p&gt;


&lt;h3&gt;La gestion des ressources&lt;/h3&gt;

&lt;p&gt;La gestion des ressources peut être perçue à plusieurs niveaux. Les langages de bas niveau tel que le C, continuent  à être sujet aux erreurs de type &lt;em&gt;buffer overflow&lt;/em&gt;. La méfiance se doit d'être de mise pour les applications critiques même si elles sont écrites en un langage de plus haut niveau car leur implémentation est bien souvent en C.&lt;/p&gt;


&lt;p&gt;Au niveau de l'applicatif, il conviendra d'être vigilant au transit des données. Ainsi, il est encore courant de voir des données critiques, par exemple relatives à l'authentification, stockées sur le poste client et transiter en clair. Interceptées, elles peuvent donner à un tiers des droits d'administration. Dans le même ordre d'idée, il est courant de voir des chemins d'accès construits à partir des requêtes et donc facilement modifiables, ce qui peut mettre en danger le système de fichiers du serveur. La protection contre l'injection de code ou contre l'exécution de code non souhaité est encore couramment observée. Enfin, bien souvent encore, les cas d'école d'oubli ou de mauvaise initialisation de variables ainsi que le mauvais contrôle des calculs sont sujets à nombre d'erreurs. Bien qu'ils puissent paraître bénins, combinés à une mauvaise gestion des erreurs, il peut s'agir de cas qui entraînent un plantage des serveurs ou une remontée d'informations critiques.&lt;/p&gt;


&lt;h3&gt;Mauvaise sécurité&lt;/h3&gt;

&lt;p&gt;Les simples brèches de sécurité sont encore monnaie courante. Cela commence par une mauvaise gestion du contrôle d'accès. Il est ainsi conseillé de bien définir les rôles des utilisateurs, mais également d'être vigilant aux autorisations horizontales&amp;nbsp;: autoriser un utilisateur ne dispense pas de vérifier qu'il accède bien à ses informations et non à celles du voisin. Ce contrôle d'accès peut être mis à mal par l'utilisation de méthodes de chiffrement fragiles ou par la gestion en dur des informations d'authentification. De même, la gestion des privilèges d'exécution de l'application est souvent simplifiée pour ne pas dire bâclée. Une application qui a besoin d'un certain niveau de privilèges élevé sur un système pour effectuer certaines opérations ne doit pas le rester indéfiniment.&lt;/p&gt;


&lt;p&gt;Enfin, avec l'avènement des clients riches, il est tentant de se reposer sur eux pour le contrôle des informations. Mais il ne faut pas oublier que ces contrôles sont exposés et très facilement modifiables. Chaque composant (client, serveur...) doit contrôler sa propre intégrité.&lt;/p&gt;


&lt;h3&gt;En conclusion (ou si vous ne devez lire qu'une partie, c'est celle là).&lt;/h3&gt;

&lt;p&gt;J'ai volontairement choisi de ne pas lister précisément les différents points de l'article du &lt;em&gt;CWE&lt;/em&gt; ni de d'entrer dans les détails des différents points afin de vous inciter à aller voir les différentes fiches. Chaque fiche CWE (&lt;em&gt;Common Weakness Enumeration&lt;/em&gt;) possède un descriptif du risque avec des exemples type et des pistes pour y remédier.&lt;/p&gt;


&lt;p&gt;Cependant, à bien y regarder, chaque &lt;em&gt;faiblesse&lt;/em&gt; paraît relativement bénigne et souvent ne pas avoir d'effet néfaste. Mais le fait est que bien souvent, il suffit de les combiner entre elles pour voir tous les dommages qu'elles peuvent causer. Prenons le cas d'un contrôle d'accès non géré horizontalement (un utilisateur A est identifié avec certains droits, le système vérifie si il a le droit d'exécuter les différentes actions mais pas si ces actions concernent ses données ou celles d'un utilisateur B de même niveau d'accréditation). Un développeur trop sûr de lui pourra se dire qu'il contrôle au niveau applicatif les accès de cet utilisateur et qu'il n'y a pas besoin de plus de sécurité. Sauf qu'il (ou un autre développeur reprenant le code) utilise pour la navigation entre différentes pages web l'identifiant de l'utilisateur en tant que paramètre de la requête. Un utilisateur mal intentionné remarquera qu'une fois authentifié, en ne modifiant que ce simple paramètre, il se donne accès à tous les comptes des utilisateurs.&lt;/p&gt;


&lt;p&gt;Ainsi, il convient d'appliquer quelques principes pourtant de base. Diffuser le minimum d'informations et contrôler les échanges. Ne pas traiter une information non vérifiée et surtout vérifier qu'elle n'entraîne pas de sortie du périmètre d'exécution de l'application. Mais surtout, ne pas oublier qu'une application s'exécute dans un certain contexte (sur un système sur lequel elle fait appel à d'autres ressources). Dans ce cadre, il convient de s'assurer que les différents composants se sécurisent eux même&amp;nbsp;: les bases de données doivent assurer leur intégrité et ne pas se reposer sur l'applicatif. Dans le même ordre d'idées, elles ne doivent pas donner des privilèges d'administrateur à toutes les applications en permanence. Il en va de même pour les logiciels externes de l'application et du système de fichier&amp;nbsp;: l'application doit s'exécuter dans un périmètre défini avec des droits définis.&lt;/p&gt;


&lt;p&gt;Il s'agit de règles simples, simples à mettre en œuvre mais hélas bien souvent oubliées.&lt;/p&gt;


&lt;p&gt;Liens&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Annonce sur le site du &lt;a href=&quot;http://www.sans.org/top25errors/?utm_source=web&amp;amp;utm_medium=text-ad&amp;amp;utm_content=Announcement_Bar_20090111&amp;amp;utm_campaign=Top25&amp;amp;ref=37029&quot; hreflang=&quot;en&quot;&gt;SANS Institute&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Annonce sur le site du &lt;a href=&quot;http://cwe.mitre.org/top25/#CWE-20&quot; hreflang=&quot;en&quot;&gt;CWE&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;</description>
    
    
    
          <comments>http://blog.netapsys.fr/index.php/post/2009/01/14/Rigueur-et-securite#comment-form</comments>
      <wfw:comment>http://blog.netapsys.fr/index.php/post/2009/01/14/Rigueur-et-securite#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.netapsys.fr/index.php/feed/rss2/comments/61</wfw:commentRss>
      </item>
    
  <item>
    <title>Introduction à Python</title>
    <link>http://blog.netapsys.fr/index.php/post/2008/09/30/Python</link>
    <guid isPermaLink="false">urn:md5:91dd1291629d4c49a7be5bef672b59bf</guid>
    <pubDate>Tue, 30 Sep 2008 09:34:00 +0200</pubDate>
    <dc:creator>Darko Stankovski</dc:creator>
        <category>Python</category>
        <category>open source</category><category>python</category><category>tutoriel</category>    
    <description>&lt;p&gt;Le monde fabuleux des langages de programmation est aujourd'hui très riche. Pour beaucoup, il se divise en langages de scripts et en langages d'applications. Les premiers permettent une écriture simple, sont interprétés et seraient destinés à des petites tâches de maintenance. Les seconds, compilés, plus complexes, seraient plus adaptés à produire de lourdes applications.&lt;/p&gt;


&lt;p&gt;Python a été conçu comme un langage de script. Cependant, son implémentation multiparadigme lui permet d'être utilisé aussi bien pour les petites tâches de maintenance, que comme une réelle application lourde. Petit tour du propriétaire.&lt;/p&gt;    &lt;p&gt;La présentation exhaustive de l'historique de Python existe un peu partout sur la toile (Wikipedia, Python.org). Mais voyons ici une présentation succincte. Python est un langage créé en 1989 au CWI par Guido Van Rossum, qui avait besoin d'un langage de script et qui n'en trouvait aucun correspondant à ses besoins. Python est inspiré de ABC, Modula 3, et du langage C. Lorsque Guido Van Rossum quitte le CNRI en 2000, Python alors en version 1.6.1 adopte une licence compatible avec la GPL. Depuis la version 2.1, Python est sous licence Python Software Foundation Licence, qui est dans les grandes lignes comparable à l'Apache Software Foundation Licence. Aujourd'hui, le développement de Python se poursuit sous la dictature bienveillante de Guido Van Rossum qui est depuis 2005 chez Google.&lt;/p&gt;


&lt;p&gt;A la date de rédaction de cet article, la version stable de Python est, depuis 2006, la 2.5. Deux versions sont prévues incessamment sous peu&amp;nbsp;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Py3k (Python 3000 en fait Python 3.0) est programmé pour octobre 2008. py3k marque un tournant car il sera incompatible avec les versions précédentes du fait de la modification profonde de certains objets propres aux langages (chaînes, dictionnaires...). Py3K s'accompagne également d'une réorganisation de l'ensemble des bibliothèques standard.&lt;/li&gt;
&lt;li&gt;Python 2.6, dont nous sommes depuis le 20 août 2008 à la Beta 3 (et dernière), est surtout destiné à permettre la transition en douceur entre le code 2.x et 3.0.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Enfin, notons que Python doit son nom aux Monthy Python, dont Guido Van Rossum était un grand fan de la série Flying Circus, et non au serpent du même nom, bien que ce dernier sorte mieux en logo.&lt;/p&gt;


&lt;h2&gt;Points d'intérêt du langage.&lt;/h2&gt;

&lt;p&gt;Python a été conçu comme un langage de script. Il est donc interprété et supporte un typage dynamique, bien qu'il soit fortement typé. Cependant, Python est avant tout un langage multiparadigme et permet aussi bien la programmation objet que fonctionnelle. Python bénéficie également d'une gestion dynamique de la mémoire à l'aide d'un mécanisme de comptage de références, il possède un système de gestion des exceptions, et est réflectif et introspectif. Python est également extensible grâce à la possibilité d'interfaçage avec des bibliothèques C. Enfin, si l'interpréteur officiel est écrit en C et le rend portable (aussi bien sous des systèmes Windows, MacOS, Linux/Unix que sous BeOS, Os2 voir des systèmes mainframe type os/400 ou z/OS), il existe diverses implémentations sous divers langages. Nous pourrons retenir Jython, implémentation en Java qui est capable par exemple d'interagir avec la bibliothèque fournie avec le SDK.&lt;/p&gt;


&lt;p&gt;Enfin, Python trouve sa place dans des applications complexes. Son champ d'applications va donc du script (des outils de gestion de la distribution Ubuntu sont en Python) à l'application critique (Python est utilisé au contrôle de vol de la NASA) en passant par la mobilité (Nokia a ouvert sa plate forme pour permettre le développement d'applications en Python pour la série des N60, des plate-formes mobiles telles qu'OpenMoko permettent le développement d'applications en Python) ou le Web (avec le serveur d'application Zope ou le framework DJango).&lt;/p&gt;


&lt;h2&gt;Comment &quot;faire du Python&quot;&amp;nbsp;?&lt;/h2&gt;

&lt;p&gt;Python est fourni avec un interpréteur qui se présente comme une console dans laquelle il est possible d'exécuter des instructions Python. Cet environnement est pratique pour tester du code et explorer les instructions utilisées. Il est cependant préférable d'utiliser l'utilitaire &lt;strong&gt;iPython&lt;/strong&gt; qui offre de nombreuses autres fonctionnalités.&lt;/p&gt;


&lt;p&gt;Pour une utilisation et une réutilisation, il est évident que le code Python se situe dans des fichiers. Comme tous scripts originaires d'Unix, ceux ci doivent commencer par un sha-bang, et d'une ligne spécifiant l'encodage comme dans l'exemple ci-dessous.&lt;/p&gt;

&lt;pre class=&quot;python&quot;&gt;&lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;#!/usr/bin/env python&lt;/span&gt;
&lt;span style=&quot;color: #808080; font-style: italic;&quot;&gt;# -*- coding: UTF-8 -*-&lt;/span&gt;&lt;/pre&gt;


&lt;h2&gt;Syntaxe Python&lt;/h2&gt;

&lt;h3&gt;Organisation des instructions&lt;/h3&gt;

&lt;p&gt;Python propose une manière originale pour écrire le code, dans le but de le rendre concis et lisible. Ainsi, du code Python s'écrit avec une instruction par ligne (bien qu'il soit possible d'en saisir plusieurs séparées par un point virgule) et les blocs sont délimités par l'indentation. Attention à ce sujet, en fonction des environnements, une série d'espaces (&quot;    &quot;) ne sera pas équivalent à une tabulation (&quot;/t&quot;). Des outils comme le plug-in PyDev pour Eclipse gère les conversions.&lt;/p&gt;


&lt;h3&gt;Quelques types simples&lt;/h3&gt;

&lt;p&gt;Les types simples en Python sont assez communs avec les autres langages&amp;nbsp;: entiers, décimaux, chaînes... Si le type sera déterminé dynamiquement, il faut savoir que Python gère deux types d'entiers&amp;nbsp;: le type &lt;strong&gt;int&lt;/strong&gt; et le type &lt;strong&gt;long&lt;/strong&gt;. Le type &lt;strong&gt;int&lt;/strong&gt; dépend de l'architecture donnée et sera le plus communément représenté sur 32 bits, taille d'un registre, ce qui permet une optimisation des calculs à base d'&lt;strong&gt;int&lt;/strong&gt;. Le type &lt;strong&gt;long&lt;/strong&gt; sera stocké en mémoire et ne sera ainsi limité que par la mémoire physique de l'ordinateur et donc virtuellement infini. Mais moins optimisé.&lt;/p&gt;


&lt;p&gt;Les chaînes de caractères sont comparables à ce qui se trouve dans les autres langages. Il faut juste savoir qu'il s'agit d'un type immuable (non modifiable) mais accessible comme une liste (voir ci dessous).&lt;/p&gt;


&lt;p&gt;Notons aussi que Python gère nativement des types tel que les complexes (z = x +iy).&lt;/p&gt;


&lt;h3&gt;Quelques types complexes...&lt;/h3&gt;

&lt;p&gt;...à ne pas confondre avec le type représentant les nombres complexes qui concluait la partie précédente.&lt;/p&gt;


&lt;p&gt;Dans les types complexes, on va retenir les listes, les tuples et les dictionnaires.&lt;/p&gt;


&lt;p&gt;Les listes sont une collection d'éléments. Il est possible d'accéder à ces éléments, d'en ajouter et d'en supprimer. Un élément peut être n'importe quel type supporté par Python. De plus, en Python, une liste est de type &lt;strong&gt;liste&lt;/strong&gt;, c'est à dire qu'elle peut contenir des éléments de types différents.&lt;/p&gt;


&lt;p&gt;Les accès à une liste peuvent se faire selon un indice ou une plage. L'exemple ci dessous crée une liste, affiche l'élément en indice 1, ajoute un élément en fin de liste, liste les éléments entre les indices 1 et 3, les éléments de l'indice 1 à la fin, utilise un indice négatif pour accéder à la liste à l'envers et le remplacement de plusieurs éléments.&lt;/p&gt;

&lt;pre class=&quot;python&quot;&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;maListe = &lt;span style=&quot;color: black;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #483d8b;&quot;&gt;'java'&lt;/span&gt;, &lt;span style=&quot;color: #483d8b;&quot;&gt;'python'&lt;/span&gt;, &lt;span style=&quot;color: #ff4500;&quot;&gt;42&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#93;&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;maListe&lt;span style=&quot;color: black;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff4500;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#93;&lt;/span&gt;
&lt;span style=&quot;color: #483d8b;&quot;&gt;'python'&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;maListe.&lt;span style=&quot;color: black;&quot;&gt;append&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #483d8b;&quot;&gt;'asp'&lt;/span&gt;, &lt;span style=&quot;color: #483d8b;&quot;&gt;'visual basic'&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;maListe&lt;span style=&quot;color: black;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff4500;&quot;&gt;1&lt;/span&gt;:&lt;span style=&quot;color: #ff4500;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#93;&lt;/span&gt;
&lt;span style=&quot;color: black;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #483d8b;&quot;&gt;'python'&lt;/span&gt;, &lt;span style=&quot;color: #ff4500;&quot;&gt;42&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#93;&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;maListe&lt;span style=&quot;color: black;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff4500;&quot;&gt;1&lt;/span&gt;:&lt;span style=&quot;color: black;&quot;&gt;&amp;#93;&lt;/span&gt;
&lt;span style=&quot;color: black;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #483d8b;&quot;&gt;'python'&lt;/span&gt;, &lt;span style=&quot;color: #ff4500;&quot;&gt;42&lt;/span&gt;, &lt;span style=&quot;color: black;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #483d8b;&quot;&gt;'asp'&lt;/span&gt;, &lt;span style=&quot;color: #483d8b;&quot;&gt;'visual basic'&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#93;&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;maListe&lt;span style=&quot;color: black;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff4500;&quot;&gt;-2&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#93;&lt;/span&gt;
&lt;span style=&quot;color: #ff4500;&quot;&gt;42&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;maListe &lt;span style=&quot;color: black;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #ff4500;&quot;&gt;1&lt;/span&gt;:&lt;span style=&quot;color: #ff4500;&quot;&gt;3&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#93;&lt;/span&gt; = &lt;span style=&quot;color: black;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #483d8b;&quot;&gt;'perl'&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#93;&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;maListe
&lt;span style=&quot;color: black;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #483d8b;&quot;&gt;'java'&lt;/span&gt;, &lt;span style=&quot;color: #483d8b;&quot;&gt;'perl'&lt;/span&gt;, &lt;span style=&quot;color: black;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #483d8b;&quot;&gt;'asp'&lt;/span&gt;, &lt;span style=&quot;color: #483d8b;&quot;&gt;'visual basic'&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Les &lt;strong&gt;tuples&lt;/strong&gt; sont un type particulier assimilable à une liste non modifiable. Les opérations pouvant être effectuées sont ainsi les mêmes que pour les listes excepté les opérations de modification.&lt;/p&gt;


&lt;p&gt;Les dictionnaires sont des collections de couples clef:valeur. La &lt;strong&gt;clef&lt;/strong&gt; doit être un élément de type non modifiable, ce qui peut être une valeur numérique, une chaîne de caractères, voir même un tuple si celui-ci n'est composé que d'éléments non modifiables (pas de liste par exemple).&lt;/p&gt;

&lt;pre class=&quot;python&quot;&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;monDico=&lt;span style=&quot;color: black;&quot;&gt;&amp;#123;&lt;/span&gt;&lt;span style=&quot;color: #483d8b;&quot;&gt;'sun'&lt;/span&gt;:&lt;span style=&quot;color: #483d8b;&quot;&gt;'java'&lt;/span&gt;, &lt;span style=&quot;color: #483d8b;&quot;&gt;'microsoft'&lt;/span&gt;:&lt;span style=&quot;color: black;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #483d8b;&quot;&gt;'asp'&lt;/span&gt;, &lt;span style=&quot;color: #483d8b;&quot;&gt;'visual basic'&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;monDico&lt;span style=&quot;color: black;&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span style=&quot;color: #483d8b;&quot;&gt;'sun'&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#93;&lt;/span&gt;
&lt;span style=&quot;color: #483d8b;&quot;&gt;'java'&lt;/span&gt;&lt;/pre&gt;


&lt;h3&gt;Les structures de contrôle&lt;/h3&gt;

&lt;p&gt;Les structures de contrôle peuvent paraître particulières à tout développeur C, Java, .Net. La structure conditionnelle est assez classique sous le format&lt;/p&gt;

&lt;pre class=&quot;python&quot;&gt;i = &lt;span style=&quot;color: #ff4500;&quot;&gt;100&lt;/span&gt;
&lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;if&lt;/span&gt; i &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&quot;color: #ff4500;&quot;&gt;1000&lt;/span&gt;:
    &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;print&lt;/span&gt; &lt;span style=&quot;color: #483d8b;&quot;&gt;'i est petit'&lt;/span&gt;
&lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;elif&lt;/span&gt; i == &lt;span style=&quot;color: #ff4500;&quot;&gt;1000&lt;/span&gt;:
    &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;print&lt;/span&gt; &lt;span style=&quot;color: #483d8b;&quot;&gt;'i est tout juste bien'&lt;/span&gt;
&lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;else&lt;/span&gt;:
    &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;print&lt;/span&gt; &lt;span style=&quot;color: #483d8b;&quot;&gt;'i est grand'&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Il y a à côté, 2 structures de boucles, les boucles &lt;strong&gt;while&lt;/strong&gt; et les boucles &lt;strong&gt;for&lt;/strong&gt;. La boucle &lt;strong&gt;while&lt;/strong&gt; est exécutée tant que la condition est vraie.&lt;/p&gt;

&lt;pre class=&quot;python&quot;&gt;i = &lt;span style=&quot;color: #ff4500;&quot;&gt;1&lt;/span&gt;
&lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;while&lt;/span&gt; i &lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span style=&quot;color: #ff4500;&quot;&gt;1000&lt;/span&gt;:
    &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;print&lt;/span&gt; &lt;span style=&quot;color: #483d8b;&quot;&gt;'i est toujours trop petit'&lt;/span&gt;
    i = i + &lt;span style=&quot;color: #ff4500;&quot;&gt;1&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;La boucle &lt;strong&gt;for&lt;/strong&gt; par contre permet d'itérer sur une collection. Elle peut être aidée pour cela avec la fonction &lt;strong&gt;range(n)&lt;/strong&gt; qui permet de générer une liste d'entier de 0 à n-1.&lt;/p&gt;


&lt;p&gt;L'exemple suivant affiche les entiers de 0 à 9&amp;nbsp;:&lt;/p&gt;

&lt;pre class=&quot;python&quot;&gt;&lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;for&lt;/span&gt; i &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;in&lt;/span&gt; &lt;span style=&quot;color: #008000;&quot;&gt;range&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: #ff4500;&quot;&gt;10&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:
    &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;print&lt;/span&gt; i&lt;/pre&gt;


&lt;p&gt;L'exemple suivant, pour lequel &lt;strong&gt;monDico&lt;/strong&gt; est défini, permet d'afficher les valeurs associées à toutes les clefs&amp;nbsp;:&lt;/p&gt;

&lt;pre class=&quot;python&quot;&gt;&lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;for&lt;/span&gt; i &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;in&lt;/span&gt; monDico.&lt;span style=&quot;color: black;&quot;&gt;keys&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:
    &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;print&lt;/span&gt; monDico&lt;span style=&quot;color: black;&quot;&gt;&amp;#91;&lt;/span&gt;i&lt;span style=&quot;color: black;&quot;&gt;&amp;#93;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Une particularité avec les boucles est l'instruction &lt;strong&gt;else&lt;/strong&gt; comme dans l'exemple ci-dessous&amp;nbsp;:&lt;/p&gt;

&lt;pre class=&quot;python&quot;&gt;&lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;for&lt;/span&gt; i &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;in&lt;/span&gt; monDico.&lt;span style=&quot;color: black;&quot;&gt;keys&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:
    &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;print&lt;/span&gt; monDico&lt;span style=&quot;color: black;&quot;&gt;&amp;#91;&lt;/span&gt;i&lt;span style=&quot;color: black;&quot;&gt;&amp;#93;&lt;/span&gt;
&lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;else&lt;/span&gt;:
    &lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;print&lt;/span&gt; &lt;span style=&quot;color: #483d8b;&quot;&gt;&amp;quot;C'est tout&amp;quot;&lt;/span&gt;&lt;/pre&gt;


&lt;p&gt;Dans un contexte de boucle, l'instruction contenue dans le &lt;strong&gt;else&lt;/strong&gt; sera exécutée après l'exécution de la boucle sauf si une instruction &lt;strong&gt;break&lt;/strong&gt; est exécutée lors des itérations.&lt;/p&gt;


&lt;h3&gt;Écriture de fonctions&lt;/h3&gt;

&lt;p&gt;Pour écrire une fonction en Python, il suffit de suivre le patron suivant&amp;nbsp;:&lt;/p&gt;

&lt;pre class=&quot;python&quot;&gt;&lt;span style=&quot;color: #ff7700;font-weight:bold;&quot;&gt;def&lt;/span&gt; maFonction&lt;span style=&quot;color: black;&quot;&gt;&amp;#40;&lt;/span&gt;mesParametres&lt;span style=&quot;color: black;&quot;&gt;&amp;#41;&lt;/span&gt;:
    &lt;span style=&quot;color: #483d8b;&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #483d8b;&quot;&gt;&amp;quot;Mon docstring&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #483d8b;&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;
    mes instructions&lt;/pre&gt;


&lt;p&gt;Si la structure est classique, un intérêt du langage Python est cette chaîne de caractères &lt;strong&gt;Mon docstring&lt;/strong&gt;. Il s'agit là d'un docstring, comparable au commentaire javadoc en java. Il est possible d'accéder spécifiquement à cette information par l'instruction&amp;nbsp;:&lt;/p&gt;

&lt;pre class=&quot;python&quot;&gt;&lt;span style=&quot;color: #66cc66;&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;maFonction.__doc__
Mon docstring&lt;/pre&gt;


&lt;p&gt;Evidemment, de nombreux outils sont capables d'exploiter les informations contenus dans les docstrings.&lt;/p&gt;


&lt;h2&gt;En conclusion&lt;/h2&gt;

&lt;p&gt;Ce billet n'a pas la prétention d'être un cours complet sur Python. Cette première introduction est destinée à présenter un langage original qui est une réponse à l'opposition entre les langages de scripting et les langages compilés. De part ses origines, Python a une sémantique éloignée des langages utilisés dans l'informatique de gestion (Java, .Net, et même C/C++) mais offre des possibilités tout aussi puissantes qui seront développées dans des billets ultérieurs.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.netapsys.fr/index.php/post/2008/09/30/Python#comment-form</comments>
      <wfw:comment>http://blog.netapsys.fr/index.php/post/2008/09/30/Python#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.netapsys.fr/index.php/feed/rss2/comments/40</wfw:commentRss>
      </item>
    
  <item>
    <title>Un JUG printanier</title>
    <link>http://blog.netapsys.fr/index.php/post/2008/06/11/Un-JUG-printanier</link>
    <guid isPermaLink="false">urn:md5:ab6044cea5da1b8a16b6367f7cea2930</guid>
    <pubDate>Wed, 11 Jun 2008 00:43:00 +0200</pubDate>
    <dc:creator>Darko Stankovski</dc:creator>
        <category>Java</category>
        <category>java</category><category>JUG</category><category>parisjug</category><category>spring</category>    
    <description>&lt;p&gt;Pour le dernier JUG Parisien de printemps, le thème était le &lt;a href=&quot;http://springframework.org/&quot;&gt;framework Spring&lt;/a&gt;. La mouture 2.5 est en effet sortie il y a environ 2 mois, accompagnée de son lot de nouveautés.&lt;/p&gt;


&lt;p&gt;Retour sur cette soirée riche en enseignements.&lt;/p&gt;    &lt;p&gt;Une des évolutions, qui concernera le plus grand monde, est l'utilisation plus importante des annotations qui permet de décharger de manière très importante les fichiers de configuration. En effet, l'une des grandes critiques que l'on pouvait faire à propos de Spring, est le volume de fichier de configuration XML. Avec cette mouture 2.5, la configuration XML devrait elle aussi être réduite puisqu'elle ne devrait concerner que la partie initiale du projet. Au développeur par la suite de tirer profit des annotations que Spring met à disposition pour alléger le code technique. Ceci a été illustré par le développement d'une fonctionnalité de Blog par la méthode des TDD (Test Driven Developement, Développement Dirigé par les Tests) par Christian Blavier au micro et Jean-François Hélie au clavier. Cette démonstration a pu mettre en avant l'avantage de cette méthode qui tire pleinement avantage de ce qu'offre Spring 2.5, ainsi que des outils associés tel que &lt;a href=&quot;http://www.unitils.org/&quot;&gt;Unitils&lt;/a&gt; qui permet de tirer profit de DBUnit et EasyMock pour les tests (plus ou moins) unitaires.&lt;/p&gt;


&lt;p&gt;La présence de Julien Dubois et Michaël Isvy, de &lt;a href=&quot;http://www.springsource.com/fr&quot;&gt;SpringSource&lt;/a&gt;, a permis d'approfondir les nouveautés de Spring 2.5. Parmi celles-ci, &lt;a href=&quot;http://static.springframework.org/spring-security/site/index.html&quot;&gt;Spring Security&lt;/a&gt;, évolution d'Acegi Security, est l'une des plus marquante. Acegi Security, bien que très bon outil de sécurité, avait comme gros défaut d'être très complexe à manipuler. Spring Security 2.0 équilibre la donne en réduisant la complexité, notamment au niveau du fichier de configuration, tout en permettant une gestion fine de la sécurité. Il est ainsi possible de  laisser Spring Security gérer les cookies d'authentification, de bloquer 2 authentifications simultanées, et par les méthodes d'interception, de gérer les autorisations d'appel de toute méthode des objets gérés par Spring. Tout cela peut faire l'objet d'un prochain billet...&lt;/p&gt;


&lt;p&gt;Pour le &lt;a href=&quot;http://springframework.org/projects&quot;&gt;reste des nouveautés&lt;/a&gt;, il faut citer Spring Dynamic Modules For OSGi(tm) Service Platforms qui a pour objectif de proposer des modules Java (et non pas juste des archives). Je vous laisse découvrir ce sujet sur la présentation disponible sous peu sur le &lt;a href=&quot;http://www.parisjug.org/xwiki/bin/view/Main/&quot;&gt;site de Paris Jug&lt;/a&gt;. On citera donc aussi Spring Batch, Spring Web Flow, Spring WebServices... Tant de projets qui apportent de manière souple des facilités pour le développement de nos applications Java.&lt;/p&gt;</description>
    
    
    
          <comments>http://blog.netapsys.fr/index.php/post/2008/06/11/Un-JUG-printanier#comment-form</comments>
      <wfw:comment>http://blog.netapsys.fr/index.php/post/2008/06/11/Un-JUG-printanier#comment-form</wfw:comment>
      <wfw:commentRss>http://blog.netapsys.fr/index.php/feed/rss2/comments/27</wfw:commentRss>
      </item>
    
</channel>
</rss>