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?
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
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
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