Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
2246 connectés 

  FORUM HardWare.fr
  Programmation
  Python

  [Python] SQLAlchemy, liste contenant plusieurs types

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[Python] SQLAlchemy, liste contenant plusieurs types

n°1767813
alien cons​piracy
hardtrance addict
Posté le 01-08-2008 à 13:59:32  profilanswer
 

Bonjour, je découvre SQLAlchemy a travers Turbogears et je suis devant un petit problème.
 
Je veux créer un modèle de galaxie à travers trois classes différentes (au final il doit y en avoir beaucoup plus) :

  • System()
  • Star()
  • Planet()


Chacunes de ces classes possède un attribut children qui est une liste contenant tout les objects qui lui sont attachés.  
Typiquement on aurait System -> Star -> Planet. Jusque là pas de problème.
Là où le problème se pose c'est si je veux que l'attribut children puisse contenir plusieurs classes, exemple:
Imaginons un systeme contenant une étoile avec ses planètes, mais également une planète qui n'est pas dans l'orbite de l'étoile
System -> Star -> Planet
           -> Planet
 
Voici le code que j'ai écris pour faire face à ce cas :

Code :
  1. # your data tables
  2. systems_table = Table('systems', metadata,
  3.                       Column('ID', Unicode, primary_key=True)
  4.                       )
  5. stars_table = Table('stars', metadata,
  6.                     Column('ID', Unicode, primary_key=True),
  7.                     Column('parent_id', Unicode, ForeignKey('systems.ID'))
  8.                     )
  9. planets_table = Table('planets', metadata,
  10.                       Column('ID', Unicode, primary_key=True),
  11.                       Column('parent_id', Unicode, ForeignKey('stars.ID'),
  12.                                                    ForeignKey('systems.ID'))
  13.                       )
  14. # your model classes
  15. class System(object):
  16.     pass
  17. class Star(object):
  18.     pass
  19. class Planet(object):
  20.     pass
  21. # set up mappers between your data tables and classes
  22. mapper(System, systems_table, properties={'children':relation(Star),
  23.                                                             'children':relation(Planet)})
  24. mapper(Star, stars_table, properties={'children':relation(Planet)})
  25. mapper(Planet, planets_table)


 
Tout va bien jusqu'a ce que je commit les changements:
 


>>> mysys = System()
>>> mystar = Star()
>>> myplanet = Planet()
>>> mysys.ID = 1
>>> mystar.ID = 2
>>> myplanet.ID = 3
>>> mylostplanet = Planet()
>>> mylostplanet.ID = 4
>>> mysys.children.append(mystar)
>>> mysys.children.append(mylostplanet)
>>> mystar.children.append(myplanet)
>>> session.flush()
...
...
...
FlushError: Attempting to flush an item of type <class 'x4m.model.Planet'> on co
llection 'System.children', whose mapper does not inherit from that of <class 'x
4m.model.Star'>.


 
Je m'en remets à vous. :)

mood
Publicité
Posté le 01-08-2008 à 13:59:32  profilanswer
 

n°1767896
multani
Dépressionnisé
Posté le 01-08-2008 à 15:38:03  profilanswer
 

Ouais, mais nan :o
 
Je sais plus ce que fais SQLAlchemy exactement pour les propriétés, mais vu que tu défini deux fois la même propriété 'children' (dans ton mapper sur la classe System), y'en a un qui écrase l'autre.
Vu le message d'erreur, on dirait qu'il garde que la relation avec Star.
 
 
Ceci dit, c'est pas vraiment un problème lié à SQLAlchemy, mais plutôt un problème de conception : ton System contient des objets, qui sont soit des Stars, soit des Planets. Et une Star contient des Planets.
 
Donc, il faut que tu généralises le concept d'objets d'un système, qui sera soit une Star, soit une Planet, et ton System contiendra ce genre d'objets.
Regarde comment faire de l'héritage avec SQLAlchemy.

n°1767902
multani
Dépressionnisé
Posté le 01-08-2008 à 15:41:57  profilanswer
 

Un truc du genre (pseudo langage)

Code :
  1. class System:
  2.    children : SystemObject list
  3.  
  4. class SystemObject(abstract):
  5.    pass
  6.  
  7. class Star(SystemObject):
  8.    children : Planet list
  9.  
  10. class Planet(SystemObject):
  11.    pass


SystemObject est une classe "abstraite", juste là pour représenter la relation de parenté entre Star et Planet.

n°1768222
alien cons​piracy
hardtrance addict
Posté le 02-08-2008 à 13:18:08  profilanswer
 

Merci beaucoup, c'est exactement ça.
Pour ceux que cela intéressent voici mon code:

Code :
  1. # your data tables
  2.  
  3. spatialobjects_table = Table('spatialobjects', metadata,
  4.                            Column('unique_ID', Unicode, primary_key=True),
  5.                            Column('name', Unicode),
  6.                            Column('children_id', Unicode, ForeignKey('spatialobjects.unique_ID')),
  7.                            Column('type', Unicode, nullable=False)
  8.                            )
  9. systems_table = Table('systems', metadata,
  10.                      Column('unique_ID', Unicode, ForeignKey('spatialobjects.unique_ID'), primary_key=True)
  11.                      )
  12. stars_table = Table('stars', metadata,
  13.                    Column('unique_ID', Unicode, ForeignKey('spatialobjects.unique_ID'), primary_key=True)
  14.                    )
  15. planets_table = Table('planets', metadata,
  16.                      Column('unique_ID', Unicode, ForeignKey('spatialobjects.unique_ID'), primary_key=True)
  17.                      )
  18. # your model classes
  19.  
  20. class SpatialObject(object):
  21.    pass
  22.  
  23. class System(SpatialObject):
  24.    pass
  25.  
  26. class Star(SpatialObject):
  27.    pass
  28.  
  29. class Planet(SpatialObject):
  30.    pass
  31.  
  32. # set up mappers between your data tables and classes
  33. mapper(SpatialObject, spatialobjects_table, polymorphic_on=spatialobjects_table.c.type, polymorphic_identity='spatialobject', properties={'children':relation(SpatialObject, backref=backref('parent', remote_side=[spatialobjects_table.c.unique_ID]))})
  34. mapper(System, systems_table, inherits=SpatialObject, polymorphic_identity='system')
  35. mapper(Star, stars_table, inherits=SpatialObject, polymorphic_identity='star')
  36. mapper(Planet, planets_table, inherits=SpatialObject, polymorphic_identity='planet')
 

Si System hérite aussi de SpatialObject c'est parcque un systeme de deux planètes peut exister dans l'orbite d'une etoile et donc dans un autre systeme plus grand. :)


Message édité par alien conspiracy le 02-08-2008 à 13:25:54
n°1796931
falifalibe
toujour heureux
Posté le 08-10-2008 à 09:28:28  profilanswer
 

salut!
j'ai vue ton mail et je voudrais savoir si sqlalchemy est une base de donnée puissant car je veux utiliser un bd avec python et je cherche un truc commme mysql, merci pour ton aide

n°1796938
KangOl
Profil : pointeur
Posté le 08-10-2008 à 09:45:31  profilanswer
 

falifalibe a écrit :

sqlalchemy est une base de donnée


non :o


---------------
Nos estans firs di nosse pitite patreye...

Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Python

  [Python] SQLAlchemy, liste contenant plusieurs types

 

Sujets relatifs
[Delphi] Conversion de types (single et string)[Java][UISpec4J] Intercepter plusieurs fenêtres
suppression d'une structure dans une liste visual c++checkbox dans select(Liste déroulante)
affichage liste sélectionnée à partir d'un selectergonomie d'un calculateur : rappeler la selection d'une liste déroul.
importation fichier > tableau dans pythonVBS : tester une liste
liste avec jbuilderModule python
Plus de sujets relatifs à : [Python] SQLAlchemy, liste contenant plusieurs types


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR