2016-01-03 17 views
5

Tôi đang cố gắng tạo cơ sở dữ liệu trong SQLite có hai bảng, một cho danh sách các sân bay và một cho danh sách chuyến đi giữa các cặp sân bay đó. Tôi đã thiết lập nó như một, nhiều-nhiều mối quan hệ tự tham chiếu:Hạn chế SQLAlchemy NOT NULL không thành công trên khóa chính

class Trips(db.Model): 

    __tablename__ = 'trips' 

    id = db.Column(db.Integer, primary_key=True) 
    airport_from = db.Column(db.Integer, db.ForeignKey('airport.id')) 
    airport_to = db.Column(db.Integer, db.ForeignKey('airport.id')) 
    price = db.Column(db.Float) 
    date = db.Column(db.Date) 

class Airport(db.Model): 

    __tablename__ = 'airport' 

    id = db.Column(db.Integer, primary_key=True) 
    iata = db.Column(db.String(8), index=True, unique=True) 
    name = db.Column(db.String(120), index=True, unique=True) 
    city = db.Column(db.String(120)) 
    region = db.Column(db.String(120)) 
    country = db.Column(db.String(120)) 

    flying_from = db.relationship('Trips', backref='end', primaryjoin=(id==Trips.airport_to)) 
    flying_to = db.relationship('Trips', backref='start', primaryjoin=(id==Trips.airport_from)) 

    def __repr__(self): 
     return '<Airport: {0}; IATA: {1}>'.format(self.name, self.iata) 

Khi tôi mở ra vỏ Python của tôi và nhập khẩu các mô hình này, tôi có phiên SQLAlchemy thêm đối tượng Sân bay và cam kết tốt , nhưng khi tôi làm điều gì đó như:

>>> t = models.Trips(airport_from=3, airport_to=4, price=230.0) 
>>> db.session.add(t) 
>>> db.session.commit() 

Nó mang lại cho tôi traceback này:

Traceback (most recent call last): 
    File "/Users/heli/nomad/flask/lib/python3.4/site-packages/sqlalchemy/engine/base.py", line 1139, in _execute_context 
context) 
    File "/Users/heli/nomad/flask/lib/python3.4/site-packages/sqlalchemy/engine/default.py", line 450, in do_execute 
cursor.execute(statement, parameters) 
sqlite3.IntegrityError: NOT NULL constraint failed: trips.id 

Trường hợp ngoại lệ trên là nguyên nhân trực tiếp của ngoại lệ sau đây:

Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/Users/heli/nomad/flask/lib/python3.4/site-packages/sqlalchemy/orm/scoping.py", line 150, in do 
    return getattr(self.registry(), name)(*args, **kwargs) 
    File "/Users/heli/nomad/flask/lib/python3.4/site-packages/sqlalchemy/orm/session.py", line 813, in commit 
    self.transaction.commit() 
    File "/Users/heli/nomad/flask/lib/python3.4/site-packages/sqlalchemy/orm/session.py", line 392, in commit 
    self._prepare_impl() 
    File "/Users/heli/nomad/flask/lib/python3.4/site-packages/sqlalchemy/orm/session.py", line 372, in _prepare_impl 
    self.session.flush() 
    File "/Users/heli/nomad/flask/lib/python3.4/site-packages/sqlalchemy/orm/session.py", line 2027, in flush 
    self._flush(objects) 
    File "/Users/heli/nomad/flask/lib/python3.4/site-packages/sqlalchemy/orm/session.py", line 2145, in _flush 
    transaction.rollback(_capture_exception=True) 
    File "/Users/heli/nomad/flask/lib/python3.4/site-packages/sqlalchemy/util/langhelpers.py", line 60, in __exit__ 
    compat.reraise(exc_type, exc_value, exc_tb) 
    File "/Users/heli/nomad/flask/lib/python3.4/site-packages/sqlalchemy/util/compat.py", line 183, in reraise 
    raise value 
    File "/Users/heli/nomad/flask/lib/python3.4/site-packages/sqlalchemy/orm/session.py", line 2109, in _flush 
    flush_context.execute() 
    File "/Users/heli/nomad/flask/lib/python3.4/site-packages/sqlalchemy/orm/unitofwork.py", line 373, in execute 
    rec.execute(self) 
    File "/Users/heli/nomad/flask/lib/python3.4/site-packages/sqlalchemy/orm/unitofwork.py", line 532, in execute 
    uow 
    File "/Users/heli/nomad/flask/lib/python3.4/site-packages/sqlalchemy/orm/persistence.py", line 174, in save_obj 
    mapper, table, insert) 
    File "/Users/heli/nomad/flask/lib/python3.4/site-packages/sqlalchemy/orm/persistence.py", line 800, in _emit_insert_statements 
    execute(statement, params) 
    File "/Users/heli/nomad/flask/lib/python3.4/site-packages/sqlalchemy/engine/base.py", line 914, in execute 
    return meth(self, multiparams, params) 
    File "/Users/heli/nomad/flask/lib/python3.4/site-packages/sqlalchemy/sql/elements.py", line 323, in _execute_on_connection 
    return connection._execute_clauseelement(self, multiparams, params) 
    File "/Users/heli/nomad/flask/lib/python3.4/site-packages/sqlalchemy/engine/base.py", line 1010, in _execute_clauseelement 
    compiled_sql, distilled_params 
    File "/Users/heli/nomad/flask/lib/python3.4/site-packages/sqlalchemy/engine/base.py", line 1146, in _execute_context 
    context) 
    File "/Users/heli/nomad/flask/lib/python3.4/site-packages/sqlalchemy/engine/base.py", line 1341, in _handle_dbapi_exception 
    exc_info 
    File "/Users/heli/nomad/flask/lib/python3.4/site-packages/sqlalchemy/util/compat.py", line 189, in raise_from_cause 
    reraise(type(exception), exception, tb=exc_tb, cause=exc_value) 
    File "/Users/heli/nomad/flask/lib/python3.4/site-packages/sqlalchemy/util/compat.py", line 182, in reraise 
    raise value.with_traceback(tb) 
    File "/Users/heli/nomad/flask/lib/python3.4/site-packages/sqlalchemy/engine/base.py", line 1139, in _execute_context 
    context) 
    File "/Users/heli/nomad/flask/lib/python3.4/site-packages/sqlalchemy/engine/default.py", line 450, in do_execute 
    cursor.execute(statement, parameters) 
sqlalchemy.exc.IntegrityError: (sqlite3.IntegrityError) NOT NULL constraint failed: trips.id [SQL: 'INSERT INTO trips (airport_from, airport_to, price, date) VALUES (?, ?, ?, ?)'] [parameters: (3, 4, 230.0, None)] 

Phần chính có vẻ là điểm mấu chốt:

sqlalchemy.exc.IntegrityError: (sqlite3.IntegrityError) NOT NULL constraint failed: trips.id [SQL: 'INSERT INTO trips (airport_from, airport_to, price, date) VALUES (?, ?, ?, ?)'] [parameters: (3, 4, 230.0, None)] 

Dường như vì tôi không đưa ra một giá trị cho các tham số id, mà nó từ chối để thêm các đối tượng. Nhưng tôi nghĩ rằng id này sẽ được tự động thêm vào và tăng lên, như đã xảy ra với tham số id của đối tượng Airport. Tôi đang thiếu gì ở đây?

Trả lời

7

Thêm rõ ràng autoincrement=True để Trips định nghĩa lớp:

id = db.Column(db.Integer, primary_key=True, autoincrement=True) 

Nếu bảng được tạo ra mà không autoincrement rõ ràng, bạn cần phải vượt qua Trips.id = NULL để tăng nó, xem https://www.sqlite.org/faq.html#q1

+2

Cảm ơn D, điều này đã làm việc! Bất kỳ ý tưởng nào về lý do tại sao tôi phải làm điều này cho Chuyến đi, nhưng không phải khi tôi thêm đối tượng Sân bay? I E. khi tôi tạo một đối tượng Airport mà không có một id rõ ràng, tôi có thể thêm nó và cam kết phiên mà không có bất kỳ vấn đề nào. – HLH

+0

Câu hỏi hay, He) Có thể bạn đang vượt qua Airport.id = NULL khi bạn tạo đối tượng Airport mới hoặc bảng Airport đã được định nghĩa trong SQLite với thuộc tính AUTOINCREMENT? – MOCKBA

+1

Tôi đã kiểm tra kỹ, và tôi đã thực hiện không, mặc dù tôi có thể bị nhầm lẫn. Nó không phải là một vấn đề lớn mặc dù, miễn là tất cả mọi thứ hoạt động – HLH

Các vấn đề liên quan