繁体   English   中英

经典问题:如何将数据插入表格:书籍,作者,book_author?

[英]Classic issue: how to insert data to tables: books, authors, book_author?

我想要3张桌子:

  • 书籍(编号,书名,自动递增编号)
  • 作者(编号,名称,自动递增(编号))
  • book_author(book_id,author_id)

我想在一个事务中完成所有操作,以确保只有在所有表中一切正常的情况下,才将数据插入表中。

要向book_author插入任何内容,我需要没有ID的ID。

我是不是该:

  1. 将数据插入到books表中,进行选择以获取ID,
  2. 将数据插入author表,进行选择以获取ID,
  3. book_author插入两个id

还是应该在插入时使用触发器? 但这是使触发器依赖于两个插入的一种方法吗?

我可以帮忙,我可以说我正在尝试使用python和sqlalchemy。


第二个问题也许很重要。...如果某些数据库不支持自动增量怎么办?

SQLAlchemy Object Relation API为您完成所有工作:添加记录,事务支持,自动增加列值。 因此,您不必费心为每个对象保存ID并为每个关系创建记录。 举例说明这一点的最佳方法:

from sqlalchemy import *
from sqlalchemy import create_engine, orm
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship

__author__ = 'vvlad'

metadata = MetaData()
Base = declarative_base()
Base.metadata = metadata


"""many-to-many relationship table"""
author_book = Table(
    'author_book', Base.metadata,
    Column('author_id',String(11),ForeignKey('author.id')),
    Column('book_id',Integer,ForeignKey('book.id')),
)

class Author(Base):
    __tablename__ = 'author'
    """SQLAlchemy's Sequence(name) for Column allows to have database agnostic autoincrement"""
    id = Column(Integer, Sequence('author_seq'), primary_key=True)
    name = Column(String(length=255))
    def __repr__(self):
        return "%s(name=\"%s\",id=\"%s\")" % (self.__class__.__name__,self.name,self.id)


class Book(Base):
    __tablename__ = 'book'

    id = Column(Integer, Sequence('book_seq'),primary_key=True)
    name = Column(String(length=255))
    """Defines many-to-many relations"""
    authors = relationship(Author,secondary=author_book,backref="books",collection_class=list)


    def __repr__(self):
        return "%s(name=\"%s\",id=\"%s\")" % (self.__class__.__name__,self.name,self.id)




db = create_engine('sqlite:////temp/test_books.db',echo=True)

#making sure we are working with a fresh database
metadata.drop_all(db)
metadata.create_all(db)

sm = orm.sessionmaker(bind=db, autoflush=True, autocommit=True, expire_on_commit=True)
session = orm.scoped_session(sm)

"""associating authors with book"""
b1 = Book(name="Essential SQLAlchemy")
a1 = Author(name="Rick Copeland")
"""associating book with author"""
a1.books.append(b1)
b2 = Book(name="The Difference Engine")
gibson = Author(name="William Gibson")
b2.authors.append(gibson)
b2.authors.append(Author(name="Bruce Sterling"))

b3 = Book(name="Pattern Recognition")
b3.authors.append(gibson)
try:
    #here your transaction start
    #adding objects to session. SQLAlchemy will add all related objects into session too
    session.add(b2)
    session.add(a1)

    session.add(b3)
    #closing transaction
    session.commit()
#remember to put specific exceptions instead of broad exception clause
except:
    """if something went wrong - rolls back session (transaction)"""
    session.rollback()

print "Book info"
b3 = session.query(Book).filter(Book.name=="Essential SQLAlchemy").one()
print b3
for author in b3.authors:
    print author


aname = "William Gibson"
print "Books of author %s" % aname
for book in session.query(Book).join(author_book).join(Author).filter(Author.name==aname).all():
    print book
    for author in book.authors:
        print author

如果将大量记录保存到表中,则在使用SELECT语句创建记录后查找记录ID可能会遇到问题。 使用触发器将使您可以轻松引用最后插入的记录。 这是一个教程

触发器还将帮助您自动增加表的ID字段。 您可以在此处查看示例。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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