HLH*_*HLH 7 python sqlite sqlalchemy flask flask-sqlalchemy
我正在尝试在SQLite中创建一个数据库,该数据库有两个表,一个用于机场列表,另一个表用于这些机场对之间的行程列表.我把它建立为一种自我参照,多对多的关系:
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)
Run Code Online (Sandbox Code Playgroud)
当我打开我的Python shell并导入这些模型时,我让SQLAlchemy会话添加Airport对象并提交就好了,但当我做类似的事情时:
>>> t = models.Trips(airport_from=3, airport_to=4, price=230.0)
>>> db.session.add(t)
>>> db.session.commit()
Run Code Online (Sandbox Code Playgroud)
它给了我这个追溯:
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
Run Code Online (Sandbox Code Playgroud)
上述异常是以下异常的直接原因:
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)]
Run Code Online (Sandbox Code Playgroud)
关键部分似乎是底线:
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)]
Run Code Online (Sandbox Code Playgroud)
它看起来是因为我没有给id参数赋值,它拒绝添加对象.但我认为这个id会自动添加并递增,就像Airport对象的id参数一样.我在这里错过了什么?
autoincrement=True向Trips类定义添加显式:
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
Run Code Online (Sandbox Code Playgroud)
如果在没有显式AUTOINCREMENT的情况下创建表,则需要传递Trips.id = NULL以使其递增,请参阅https://www.sqlite.org/faq.html#q1