views:

66

answers:

2

I am having trouble in making my models to generate foreign keys as not null in Web2py. I have tried everything that I knew and all that I could find on the web. Here is a simple example:

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)
);
=============

Looks like web2py ignored notnull=True for some reason.

I also tried few workarounds like giving default='' but did not help. Here is another example with MySQL backend

db = DAL('mysql://test:test@localhost: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

In MySQL it not only ignored notnull but made the column 'DEFAULT NULL' as you can see column 'prop_id'. Anybody has any idea ? How to make web2py to add 'NOT NULL' for foreign keys ?

Note: It does not make any difference if default='' is removed. I added it as per @simplyharsh suggestions and discussion here http://www.mail-archive.com/[email protected]/msg12879.html

A: 

When notnull=True is set, you should also set a default attribute.

Consider this thread.

simplyharsh
Thanks! I tried that by setting default='' but it did not work. It did no difference in create table statement. Also tested it with MySQL backend and found the same behaviour.
harry
A: 

I am assuming you don't want the foreign key to be null, because it should correspond to something that exists already. Have you tried something along the lines of

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