我想要3张桌子:
我想在一个事务中创建所有内容,以确保只有在所有表中一切正常时才会将数据插入到表中。
要向book_author
插入任何内容,我需要id,而我没有。
我应该:
books
表,进行选择以获取ID,author
表,进行选择以获取ID,id
插入book_author
或者我应该在插入时使用触发器?但这是一种使触发器依赖于两个插入的方法吗?
我会帮忙,我可以说我正在尝试使用python和sqlalchemy。
第二个问题也许这很重要......如果某个数据库不支持自动增量怎么办?
答案 0 :(得分:2)
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
答案 1 :(得分:0)