Dans une application Django, j'essaie d'accéder à une base de données MySQL existante créée avec Hibernate (java orm). Je renverse l'ingénierie du modèle utilisant: Ceci crée un fichier de modèles agréable de la base de données et de nombreuses choses étaient très bien. Mais je ne trouve pas comment accéder correctement à des champs booléens, qui ont été mappés par Hibernate en tant que colonnes de type bit (1). P> Le script InspectDB par défaut crée ces champs dans le modèle en tant que Textfield et ajoute un commentaire disant qu'il ne pouvait pas obtenir de manière fiable le type de champ. Je les ai changés vers Booleanfield mais ouvrit mes objets de modèle à l'aide de l'administrateur, mais cela ne fonctionne pas (les objets du modèle récupèrent toujours une valeur de vrai pour ces champs). L'utilisation d'Integerfield ne fonctionnera pas également (par exemple dans l'administrateur, ces champs affichent des caractères non-ASCII étranges). P> Toute suggestion de cela sans changer la base de données? (J'ai besoin des mappages Hibernate existants et de l'application Java pour travailler toujours avec la base de données). P> Info supplémentaire: J'ai laissé ces champs sous forme de booleanfield et utilisé le shell interactif pour examiner les valeurs récupérées. Ils sont retournés comme «\ x00» (lorsque la valeur Java / Hibernate est FALSE) et «\ x01» (lorsque c'est vrai), au lieu de Python Boolean Valeurs «True» et «False». P>
class AppUser(models.Model):
account_expired = models.BooleanField()
account_enabled = models.BooleanField(blank=True)
# etc...
6 Réponses :
Je suppose que le seul moyen est de sous-classement, de dire, de booleanfield et de remplacer les fonctions de TO_PYTHON / GET_PREP_VALUE, de sorte que le champ fonctionne de manière transparente avec Django et votre dB. p>
Génial, ça résolu. Depuis que j'utilise django 1.1.1, j'ai dû utiliser get_db_prep_value au lieu de get_prep_value. Voir la solution détaillée ci-dessous
Je suis en cours d'exécution Django 1.3 et j'ai sous-classé Booleanfield pour retourner vrai / faux lorsqu'il obtient une Y / N dans le champ Chari-champ sous-jacent, mais cela ne fonctionne pas. Même si j'ai sous-classé Booleanfield, la valeur de retour est U "Y" ou U "N". Je l'ai rencontré dans le débogueur et il n'appelle jamais ma méthode to_python (). Des idées?
Ron, vous voudrez peut-être vérifier cette métaclass docs.djangoproject.com/fr/1.3/howto/custom-model-fields/...
Ceci est la solution détaillée de la suggestion de Dmitry:
ma classe de terrain dérivée: p> champs de mon modèle: p>
Juste une petite chose, j'ai changé MysqlboolantAlfield vers Hibernateboolfield, car le problème booléen est pertinent pour hiberner, pas MySQL. Merci beaucoup pour votre question / réponse, cela m'a aidé!
J'ai dû faire appel au même problème, mais plutôt que de sous-classer le champ, j'ai étendu le backend MySQL pour comprendre la voie hibernée. Ce ne sont que quelques lignes de code et ont l'avantage que l'introspection de la DB puisse être faite pour fonctionner correctement.
le voir ici. strong> p> hibernateboolsbackend / backends / mysql / base.py h3>
@Phalgun, Iv'e a mis à jour le lien brisé. BTW +1 pour une solution suggérée, fonctionne bien avec django 1.65 code> + mysql code> + hibernate code>
@Ben Anhalt tu es mon héros.
Pour le faire fonctionner sur Django 1.7.1 Je dois modifier la fonction "TO_PYTHON" car elle ne fonctionnait pas pour lire correctement les données de la DB:
def to_python(self, value):
if value in (True, False): return value
if value in ('t', 'True', '1', '\x01'): return True
if value in ('f', 'False', '0', '\x00'): return False
Le paquet plus facile que de rouler le vôtre et testé sur plusieurs versions Django et Python . p> p>
dans le type booléen python est une sous-classe d'entier mais alors que Java il est de type de type. Donc, dans dB pour le type de données de champ booléen python doit être un tinytin à la place du type de bit. p>
en raison de la raison ci-dessus, l'application se comporte de manière inattendue de manière inattendue Si nous ajoutons un champ booléen dans le modèle Django et exécutez la migration, alors migrez, il ajoutera une colonne de type Tinyint au lieu du bit. P>
Donc, la mise à jour du type de colonne sur Tinyint devrait résoudre le problème. p> \ x00 code> et \ x01 code> valeur. p>