Les cartographes multiples pour la même classe dans différentes bases de données
-
19-09-2019 - |
Question
Je travaille actuellement sur une API Wikipedia ce qui signifie que nous avons un base de données pour chaque langue que nous voulons utiliser. La structure de chaque base de données est identique, ils ne diffèrent que dans leur langue. Le seul lieu où ces informations sont stockées est au nom de la base de données.
Lors du démarrage d'une langue, l'approche avant d'utiliser un droit correspondance entre les tables aux classes nécessaires (par exemple la page) avait l'air bien. Nous avons défini un moteur et des métadonnées correspondant. Lorsque nous avons ajouté une seconde base de données avec sa propre configuration pour le moteur et les métadonnées nous avons couru dans la erreur suivant:
ArgumentError:
Class '<class 'wp.orm.types.pages.Page'>' already has a primary mapper defined.
Use non_primary=True to create a non primary Mapper.clear_mappers() will remove
*all* current mappers from all classes.
J'ai trouvé un email dire qu'il doit y avoir au moins un primaire de r Mappe, donc utiliser cette option pour toutes les bases de données ne semble pas possible.
L'idée suivante consiste à utiliser sharding. Pour cela, nous devons trouver un moyen de distinguer entre les bases de données du point de vue d'une instance, comme noté dans la documentation :
"Vous avez besoin d'une fonction qui peut revenir un seul identifiant de tesson, étant donné une instance être sauvé; c'est appelé "Shard_chooser"
Je suis coincé ici. Y at-il un moyen d'obtenir le nom de la base de données donné une Objet il est chargé à partir? Ou la possibilité d'ajouter un attribut statique basée sur le moteur? L'alternative serait d'ajouter une colonne de langue à tous les la table qui est juste laid. Suis-je supervisais d'autres possibilités? Toute idée comment définir plusieurs cartographes pour la même classe, qui cartographient contre des tables dans différents bases de données?
La solution
J'ai posé cette question sur une liste de diffusion et a obtenu cette réponse par Michael Bayer :
si vous souhaitez des classes distinctes indiquent qu'ils « appartiennent » dans un
base de données, et vous avez très lignes claires quant à la façon dont cela est
effectué, utilisez le « entity_name » concept décrit à http://www.sqlalchemy.org/trac/wiki/UsageRecipes/EntityName . cela ressemble beaucoup à votre utilisation cas.L'idée suivante consiste à utiliser sharding. Pour cela, nous devons trouver un moyen de distinguer entre les bases de données du point de vue d'une instance, comme il est indiqué dans les docs: « Vous avez besoin d'une fonction qui peut renvoyer un seul identifiant de tesson, étant donné un par exemple à enregistrer; on appelle cela "shard_chooser"
sharding horizontal est une méthode de stocker de nombreux homogènes instances sur plusieurs bases de données, avec le implication que vous créez un grande base de données « virtuelle » entre partitions - le concept principal est qu'une instance individuelle obtient placés dans des partitions différentes en fonction sur certains jeux de règles. Ceci est un peu comme votre cas d'utilisation aussi bien, mais depuis vous avez une délimitation très simple i pense que l'approche « nom entité » est plus facile.
L'idée de base est de générer des sous-classes anonymes pour chaque mappage désiré qui se distinguent par la entity_name . Les détails peuvent être trouvés dans Michaels lien