2010-08-06 5 views
2

J'ai des difficultés à faire en sorte que mes modèles génèrent des clés étrangères non nulles dans Web2py. J'ai essayé tout ce que je savais et tout ce que je pouvais trouver sur le web. Voici un exemple simple:Comment ajouter une contrainte NOT NULL sur des clés étrangères dans Web2py

db = DAL('sqlite://storage.db') 
users=db.define_table('user', Field('name')) 
cars=db.define_table('cars', Field('user', users, notnull=True), Field('Model')) 
print db._lastsql 

This print === 
CREATE TABLE cars(
    id INTEGER PRIMARY KEY AUTOINCREMENT, 
    user INTEGER REFERENCES users(id) ON DELETE CASCADE, 
    Model CHAR(512) 
); 
============= 

On dirait que web2py est ignoré notnull = Vrai pour une raison quelconque.

J'ai également essayé quelques solutions de contournement comme par défaut = '' mais n'a pas aidé. Voici un autre exemple avec MySQL back-end

db = DAL('mysql://test:[email protected]:3306/test') 
db.define_table('property', 
    Field('type', notnull=True), 
    Field('area','integer', notnull=True), 
    Field('rooms','integer', default = 0, notnull=True)) 

db.define_table('media', 
    Field('title', length = 30), 
    Field('file', 'upload', autodelete=True, notnull=True), 
    Field('prop_id', db.property, notnull=True, default='', required=True)) 

CREATE TABLE SQL: 
CREATE TABLE `propdb`.`media` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `title` varchar(30) DEFAULT NULL, 
    `file` varchar(512) NOT NULL, 
    `prop_id` int(11) DEFAULT NULL, 
    PRIMARY KEY (`id`), 
    KEY `prop_id__idx` (`prop_id`), 
    CONSTRAINT `prop_media_ibfk_1` FOREIGN KEY (`prop_id`) REFERENCES `prop_property` (`id`) ON DELETE CASCADE 
) ENGINE=InnoDB DEFAULT CHARSET=utf8 

MySQL non seulement ignoré notnull mais fait la colonne « NULL DEFAULT » comme vous pouvez le voir colonne « prop_id ». Quelqu'un a une idée? Comment faire web2py pour ajouter 'NOT NULL' pour les clés étrangères?

Remarque: Cela ne fait aucune différence si default = '' est supprimé. Je l'ai ajouté selon @simplyharsh suggestions et discussion ici http://www.mail-archive.com/[email protected]/msg12879.html

+0

Btw certaines mises à jour. J'ai abandonné l'utilisation de web2py pour mon projet. Au départ, cela semblait très facile, mais il est devenu de plus en plus difficile de changer la logique magique web2py. Retour à django maintenant. – harry

+0

Je pense que web2py ORM est bien meilleur et plus simple que django ORM. Je pourrais faire des requêtes assez complexes avec web2py ORM. Je pourrais écrire (id == 1) && (nom == 'test'). Dans django, je retombe principalement sur les instructions SQL, même pour des requêtes modérément complexes. – harry

+0

Il y a un problème pour cela dans le tracker web2py: http://code.google.com/p/web2py/issues/detail?id=1395 (je ne sais pas pourquoi il n'est pas corrigé) – User

Répondre

1

Lorsque notnull=True est défini, vous devez également définir un attribut par défaut.

Considérez ceci thread.

+0

Merci! J'ai essayé cela en définissant default = '' mais cela n'a pas fonctionné. Il n'a fait aucune différence dans l'instruction create table. Également testé avec backend MySQL et trouvé le même comportement. – harry

0

Je suppose que vous ne voulez pas que la clé étrangère soit nulle, car elle devrait correspondre à quelque chose qui existe déjà. Avez-vous essayé quelque chose le long des lignes de

db.property.area.requires=IS_IN_SET([Insert your list/array of possibilities]) 
0

notnull = True dans le contexte de DAL web2pys signifie:

Le contenu de ce champ jamais être 'null' (false), la conséquence est que les sélections pour les colonnes de chaînes renverront une chaîne vide, les colonnes entières ou flottantes renverront la valeur 0 au lieu de NULL (DAL: None ou false).

Pour forcer l'utilisateur web2py à insérer une valeur, vous devez définir le widget requis du champ. Par exemple:

db.tablefoo.fieldbar.requires = IS_IN_SET('OK', 'NOT OK')