根据表名获取对应的ORM类引用
def get_class_by_tablename(tablename):
for cls in Base._decl_class_registry.values():
if hasattr(cls, '__table__') and cls.__table__.fullname == tablename:
return cls
print( get_class_by_tablename('tb_Tracks') )
检验是否已存在数据再插入
参考:SQLAlchemy commit(), flush(), expire(), refresh(), merge() - what's the difference?
以下方法先称为session.merge()方法
, 它能极快的完成插入之前的数据是否重复的检验:
user1 = User.query.get(1)
user1.name # ==> 'user1'
new_user = User(user_id=1) # ==> a second in-memory object with the same key!
new_user.name = 'user2'
user1.name # ==> 'user1'. Without merging, user1 doesn't know it is the same as new_user
db.session.merge(new_user)
user1.name # ==> 'user2'. Now updated in memory. Note not yet updated in db, needs flush() and commit()
定义复合主键
有时候表中不是以单一的主键来标示一条数据的唯一定位,而是以组合主键的方式。比如订单表中的订单号和商品号组合,两者单独的话都会有重复数据,组合起来才能定位到一个具体销售出的商品。
SQLAlchemy定义组合主键的有两种方法:直接定义primarykey,或使用PrimaryKeyConstraint
。
注意:
- 一旦定义了多重主键,那么插入数据时候即使在某一个ID上重复了,只要不是组合ID全部重复,就没有问题。
- 有了多重主键,就无需作为序列号的id来撑场面了。
方法一:直接定义
class User(Base):
field1 = Column(Integer, primary_key=True)
field2 = Column(Integer, primary_key=True)
方法二:使用PrimaryKeyConstraint(需要导入相关)
class User(Base):
field1 = Column(Integer)
field2 = Column(Integer)
__table_args__ = (
PrimaryKeyConstraint('field2', 'field1'),
{},
)
ORM类多文件定义
因为要想各个ORM类互相沟通,互相引用ID,首先要保证他们在一个Base
之中才行。
所以,最简单的方法是在一个单独文件中定义Base = declarative_base()
,然后所有的ORM文件都引用统一个Base,这样就挂钩在一起了。
同理,为了方便,我们也可以把engine
都放进来:
common_base.py:
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
engine = create_engine('sqlite:///memory:', echo=True)
然后在另一个文件ORM.py
中直接引用:
from common_base import Base, engine
这样一来,以后所有ORM文件就可以正常的互相import
了。
注意:不要把session放进来,因为session最好用完随时close()。同理,使用时,也要注意engine的使用,不要长时间连接而不关闭。
网友评论