简体   繁体   中英

FOREIGN KEY constraint failed in Web2py

I've below two tables in tables.py -

db.define_table('spr_details',
Field('SPR_name', 'string', unique=True, notnull=True),
Field('Object_location',notnull=True),
Field('NSK_System',notnull=True,),
primarykey = ['SPR_name'],migrate=True)

db.define_table('my_master_table',
Field('Test_id',notnull=True),
Field('Test_suite',notnull=True),
Field('Test_category',notnull=True),
Field('Test_unit',notnull=True),
Field('Test_case',notnull=True),
Field ('Applicability', db.spr_details,'string'),migrate=True)

I inserted one row in spr_details table. Now when I am inserting record in my_master table, I am selecting previously inserted value from Applicability drop-down column. But on submitting it, I am getting

FOREIGN KEY constraint failed error.

below is the stack trace -

Stack trace

Traceback

 Traceback (most recent call last):
  File "C:\Users\pandeyar\Downloads\web2py_src\web2py\gluon\restricted.py", line 219, in restricted
    exec(ccode, environment)
  File "C:/Users/pandeyar/Downloads/web2py_src/web2py/applications/JDBC_E2E/controllers/default.py", line 183, in <module>
  File "C:\Users\pandeyar\Downloads\web2py_src\web2py\gluon\globals.py", line 419, in <lambda>
    self._caller = lambda f: f()
  File "C:/Users/pandeyar/Downloads/web2py_src/web2py/applications/JDBC_E2E/controllers/default.py", line 99, in admin
    user_signature=False,
  File "C:\Users\pandeyar\Downloads\web2py_src\web2py\gluon\sqlhtml.py", line 3338, in smartgrid
    user_signature=user_signature, **kwargs)
  File "C:\Users\pandeyar\Downloads\web2py_src\web2py\gluon\sqlhtml.py", line 2534, in grid
    onsuccess=oncreate)
  File "C:\Users\pandeyar\Downloads\web2py_src\web2py\gluon\html.py", line 2300, in process
    self.validate(**kwargs)
  File "C:\Users\pandeyar\Downloads\web2py_src\web2py\gluon\html.py", line 2238, in validate
    if self.accepts(**kwargs):
  File "C:\Users\pandeyar\Downloads\web2py_src\web2py\gluon\sqlhtml.py", line 1965, in accepts
    self.vars.id = self.table.insert(**fields)
  File "C:\Users\pandeyar\Downloads\web2py_src\web2py\gluon\packages\dal\pydal\objects.py", line 753, in insert
    ret = self._db._adapter.insert(self, row.op_values())
  File "C:\Users\pandeyar\Downloads\web2py_src\web2py\gluon\packages\dal\pydal\adapters\base.py", line 486, in insert
    raise e
  File "C:\Users\pandeyar\Downloads\web2py_src\web2py\gluon\packages\dal\pydal\adapters\base.py", line 481, in insert
    self.execute(query)
  File "C:\Users\pandeyar\Downloads\web2py_src\web2py\gluon\packages\dal\pydal\adapters\__init__.py", line 67, in wrap
    return f(*args, **kwargs)
  File "C:\Users\pandeyar\Downloads\web2py_src\web2py\gluon\packages\dal\pydal\adapters\base.py", line 412, in execute
    rv = self.cursor.execute(command, *args[1:], **kwargs)
sqlite3.IntegrityError: FOREIGN KEY constraint failed

Any help would be extremely helpful.

Please refer to the documentation on keyed tables (ie, tables whose primary key is not the default auto-incrementing integer ID field), as spr_details is such a table.

Note, there are two problems with your reference field definition:

    Field('Applicability', db.spr_details, 'string')

First, as noted in the documentation, when referencing a keyed table, the format for the type argument to Field() must be 'reference tablename.fieldname' , not db.tablename . Second, you do not separately specify the type of a reference field (ie, you should not pass 'string' as the third argument to Field() , as the third argument is the length argument, not the type -- the type is inferred based on the type of the referenced field). So, the field definition should be:

    Field('Applicability', 'reference spr_details.SPR_name')

Note, with your current incorrect definition of the Applicability field, the field becomes an integer field (as it expects to store a reference to an integer ID field in the foreign table). If you attempt to insert an integer, you will get a foreign key constraint failure error, and if you attempt to insert a string, you will get an error about inserting a string where an int is expected. You should not get any errors if you use the correct field definition as shown above and insert string values that match values that exist in the db.spr_details.SPR_name field.

Also note that web2py assumes keyed tables will be used together (ie, both the referenced and the referencing table will be keyed). So, for example, if you use SQLFORM with my_master_table , by default it will assume that because my_master_table is not keyed, neither is the spr_details table that it references. It will therefore attempt to convert the value of SPR_details to an integer ID (which results in a conversion to 0 , which leads to a foreign key constraint error). To work around this, you should handle the database inserts and updates manually -- for example:

form = SQLFORM(db.my_master_table).process(dbio=False)
if form.accepted:
    db.my_master_table.insert(**form.vars)

Above, setting dbio=False prevents SQLFORM from doing the insert itself (which will result in an error). Instead, the insert is done explicitly using the values in form.vars .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM