我有一个关于如何向数据库添加新但唯一的项目的问题。
app = Flask(__name__, template_folder='templates')
app.config.from_object('config')
db = SQLAlchemy(app)
类看起来像这种多对多的实现:
connections = db.Table('connections', db.metadata,
db.Column('book_id', db.Integer, db.ForeignKey('books.id')),
db.Column('author_id', db.Integer, db.ForeignKey('authors.id'))
)
class Author(db.Model):
__tablename__ = 'authors'
__searchable__ = ['a_name']
__table_args__ = {'sqlite_autoincrement': True,}
id = db.Column(db.Integer, primary_key=True)
a_name = db.Column(db.String(80), unique=True)
def __repr__(self):
return unicode(self.a_name)
class Book(db.Model):
__tablename__ = 'books'
__searchable__ = ['b_name']
__table_args__ = {'sqlite_autoincrement': True,}
id = db.Column(db.Integer, primary_key=True)
b_name = db.Column(db.String(80), unique=True)
authors = db.relationship('Author', secondary=lambda: connections,
backref=db.backref('books'))
def __repr__(self):
return unicode(self.b_name)
我想只添加唯一的数据库项目。如果我要写这段代码:
author = Author(a_name = "Author1")
book = Book(b_name = "Book1")
author.books.append(book)
db.session.add(author)
db.session.add(book)
db.session.commit()
我们已经有了a_name" Author1"在我们的数据库中会有错误的例外。
IntegrityError: (IntegrityError) column a_name is not unique u'INSERT INTO authors (a_name) VALUES (?)' (u'\u0410\u0432\u0442\u043e\u04402',)
我是否需要检查这种特殊情况的独特性以及如何?还是有另一种最佳解决方案?
答案 0 :(得分:1)
ORM并不支持" MERGE"方法(例如" INSERT OR REPLACE"以及所有这些),并且那些也有很多并发症。我使用unique object食谱或其中的一些变体。当我进行大数据合并时,我会经常将一些特定块处理的整个对象集合加载到字典中,因此只需要一个SELECT语句加载它们,然后在我继续时检查该字典。
答案 1 :(得分:1)
实际上我发现不容易解决方案和丑陋的解决方案:),但它确实有效。 当然,当我使用大型数据库时,我会使用@zzzeek介绍的unique object配方。
new_author = Author(a_name = request.form['author'])
new_book = Book(b_name = request.form['book'])
author_in_db = Author.query.filter_by(a_name=unicode(new_author)).first()
book_in_db = Book.query.filter_by(b_name=unicode(new_book)).first()
# both author and book are new and unique
if unicode(new_author) != unicode(author_in_db) and \
unicode(new_book) != unicode(book_in_db):
new_author.books.append(new_book)
db.session.add(new_author)
db.session.add(new_book)
db.session.commit()
# just book is not unique
elif unicode(new_author) != unicode(author_in_db):
new_author.books.append(book_in_db)
db.session.add(new_author)
db.session.commit()
# just author is not unique
elif unicode(new_book) != unicode(book_in_db):
author_in_db.books.append(new_book)
db.session.add(new_book)
db.session.commit()
答案 2 :(得分:1)
class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String, unique=True)
fullname = Column(String)
password = Column(String)
insert_command = User.__table__.insert(
prefixes=['OR IGNORE'],
values=dict(name='MyName', fullname='Slim Shady', password='******')
)
session.execute(insert_command)
session.commit()
替换也适用
prefixes=['OR REPLACE']