[gull] pgsql...aaaarh

Marc SCHAEFER schaefer at alphanet.ch
Thu Jun 16 14:14:02 CEST 2005


On Thu, Jun 16, 2005 at 02:12:38PM +0200, Cedric BRINER wrote:
> DROP TABLE test;
> DROP TABLE new_test;

suivant la version de PostgreSQL il faut aussi supprimer les séquences
(pas dans les versions récentes à ma connaissance).

> CREATE TABLE test (id serial NOT NULL UNIQUE, nom varchar(32));

si c'est un PRIMARY KEY, autant le dire, non?

> SELECT * from test_id_seq ;
> SELECT * from new_test_id_seq ;
> --- est-ce normal d'avoir une difference pour la colonne ``log_cntOB''

désolé, je ne vois pas ce que c'est.  Extrait ?

> ALTER TABLE new_test RENAME TO test;
> --- 3)   est-ce vraiment utile de faire ce genre de manipulation. Car mes scripts recupere
> --- --   les erreurs du genre ``ERROR:  duplicate key violates unique constraint "test_id_key"''
> ---      et puisque c'est ce meme script qui a nomme cette contrainte >test_id_key<, ils peut des lors s'avoir
> ---      qu'elle operation entreprendre.

il ne devrait pas y avoir de telle violation de contrainte si les
données initiales sont cohérentes.  Si tu as oublié de faire le
setval() -- ou de remplacer le DEFAULT comme tu viens de faire,
effectivement, les prochaines insertions peuvent produire de telles
erreurs.

> ---      En fait, je me demandais si il n'y aurait-il moyen pas moyen depuis pypgsql (python postgresql)
> ---      de recuperer une sorte de description de la DB et de savoir des lors que >test_id_key< est une 
> ---      contrainte d'unicite sur le couple ( table:>test<, colonne:>id< )???

oui, la base s'auto-décrit:

 Schéma des métadata, comment trouver les informations dans les métadata 
 Méthode standard SQL: Information Schema
    /usr/share/doc/postgresql-doc/html/information-schema.html 

     information_schema

        schaefer=> \dt information_schema.*
                                List of relations
               Schema       |          Name           | Type  |  Owner   
         information_schema | sql_features            | table | postgres
         information_schema | sql_implementation_info | table | postgres
         information_schema | sql_languages           | table | postgres
         information_schema | sql_packages            | table | postgres
         information_schema | sql_sizing              | table | postgres
         information_schema | sql_sizing_profiles     | table | postgres
        (6 rows)

        schaefer=> \dv information_schema.*
                                   List of relations
               Schema       |              Name               | Type |
Owner   
         information_schema | applicable_roles                | view | postgres
         information_schema | check_constraints               | view | postgres
         information_schema | column_domain_usage             | view | postgres
         information_schema | column_privileges               | view | postgres
         information_schema | column_udt_usage                | view | postgres
         information_schema | columns                         | view | postgres
         information_schema | constraint_column_usage         | view | postgres

         [ ... ]

        schaefer=> CREATE TABLE simple(nom TEXT);
        CREATE TABLE
        schaefer=> CREATE TABLE complexe(nom TEXT NOT NULL);
        CREATE TABLE

        schaefer=> SELECT * FROM information_schema.columns;

 Méthode spécifique PostgreSQL (contenant également des extensions à SQL) 
     system catalogs (catalog-pg-class.html)
        pg_class
           SELECT * FROM pg_class WHERE (relinkind = 'r')
                                        AND (relname = 'bla');

        pg_attribute
           SELECT attname FROM pg_attribute WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = 'bla');

        pg_type
           SELECT * FROM pg_type where oid = 25;

     etc.

> DROP SEQUENCE new_test_id_seq ;
> --- ERROR:  cannot drop sequence new_test_id_seq because table test column id requires it
> --- HINT:  You may drop table test column id instead.
> --- et la j'ai une erreur de pgsql... table >test< column >id< requires it ??

Alors, ça, on dirait un bug.  Faire un exemple et envoyer à la liste de
développement.

je n'ai pas le temps de refaire
 
> 5) si m'a base est en prod, je devrais faire ce genre de truc entre un begin commit ?

PostgreSQL -- du moins quand j'avais vérifié -- ne transactionne pas les
méta-opérations (CREATE TABLE, etc), au contraire d'Oracle par exemple.
Donc activer les transactions ne sert pas à grand chose dans ce cas.
Par contre, il faudrait rendre atomique le DROP test; ALTER TABLE test_
...

Malheureusement à ma connaissance c'est impossible avec PostgreSQL. Il y aura donc une
fenêtre de vulnérabilité où d'autres backend ne verront plus de table
test.

Je poserais cette question sur la liste.

PS: si tu fais

   BEGIN WORK;
      TRUNCATE test;
      INSERT INTO test SELECT ...
   COMMIT WORK;

là tu devrais avoir une certaine sécurité. Suivant la version de
l'application, il te faudrait spécifier un niveau d'isolation
transactionnel différent et gérer d'éventuels aborts de transactions (en
SERIALIZED en particulier).

Par contre cela sera plus lent qu'un ALTER TABLE.

> >    SELECT * INTO new_test FROM test;
> 6) est-ce la maniere recommendee (best practice??)

aucune idée; elle ne crée pas les contraintes qu'il faut ajouter à la
main.

> P.-S. desole pour les caractere accentues qui se transforme dans mon mutt en ``?''. Probleme
> de conf. peut-etre ?

export LC_CTYPE=fr_CH.ISO8859-1  # et avoir généré cette locale avec dpkg-reconfigure locales



More information about the gull mailing list