[英]SQLAlchemy Core deduplication of common columns between tables
假设我要创建以下三个表:
a = db.Table(
'a', metadata,
db.Column('id', db.Integer, nullable=False, primary_key=True),
db.Column('created', server_default=func.now()),
db.Column('updated', server_default=func.now(), onupdate=func.current_timestamp()),
db.Column('unique_to_a', db.INTEGER, nullable=True)
)
b = db.Table(
'b', metadata,
db.Column('id', db.Integer, nullable=False, primary_key=True),
db.Column('created', server_default=func.now()),
db.Column('updated', server_default=func.now(), onupdate=func.current_timestamp()),
db.Column('unique_to_b', db.INTEGER, nullable=True)
)
c = db.Table(
'c', metadata,
db.Column('id', db.Integer, nullable=False, primary_key=True),
db.Column('created', server_default=func.now()),
db.Column('updated', server_default=func.now(), onupdate=func.current_timestamp()),
db.Column('a_id', db.Integer, db.ForeignKey('a.id'), index=True, nullable=True),
db.Column('unique_to_c', db.INTEGER, nullable=True)
)
所有三个( id
, created
和updated
)之间都有公共列,以及每个列都有唯一的列。
有没有一种简单的方法来创建可以拥有所有共享列的基表?
例如
base_table = db.Table(
'base', metadata,
db.Column('id', db.Integer, nullable=False, primary_key=True),
db.Column('created', server_default=func.now()),
db.Column('updated', server_default=func.now(), onupdate=func.current_timestamp()),
)
a = db.Table(
'a', metadata,
base_table,
db.Column('unique_to_a', db.INTEGER, nullable=True)
)
我们宁愿在SQLAlchemy Core中完成所有操作(即不使用ORM)。
我们之前使用过deepcopy
( from copy import deepcopy
),但我们认为必须有一种更好的方法来在表之间共享列。
据我所知, Table
不能继承,但declarative
模型可以,你可以利用它来创建表对象:
engine = create_engine("sqlite://")
Base = declarative_base()
Base.metadata.bind = engine
class BaseColumn(object):
id = Column('id', Integer, nullable=False, primary_key=True)
created = Column('created', server_default=func.now())
updated = Column('updated', server_default=func.now(), onupdate=func.current_timestamp())
class A(Base, BaseColumn):
__tablename__ = "a"
a_column = Column('unique_to_a', INTEGER, nullable=True)
print `A.__table__`
输出:
Table('a', MetaData(bind=Engine(sqlite://)), Column('id', Integer(), table=<a>, primary_key=True, nullable=False), Column('created', NullType(), table=<a>, server_default=DefaultClause(<sqlalchemy.sql.functions.now at 0x105bce490; now>, for_update=False)), Column('updated', NullType(), table=<a>, onupdate=ColumnDefault(<sqlalchemy.sql.functions.current_timestamp at 0x105bce750; current_timestamp>), server_default=DefaultClause(<sqlalchemy.sql.functions.now at 0x105bce610; now>, for_update=False)), Column('unique_to_a', INTEGER(), table=<a>), schema=None)
任何使用asyncpgsa和sqlalchemy核心而不使用deepcopy
人的解决方法:
def base_columns():
return {
Column('created_at',
DateTime(timezone=True),
server_default=func.clock_timestamp()),
Column('modified_at',
DateTime(timezone=True),
server_default=func.clock_timestamp(),
onupdate=func.clock_timestamp()),
}
company_tbl = Table(
'company', metadata,
Column('id', BigInteger, primary_key=True),
Column('name', Text, nullable=False, unique=True),
*base_columns(),
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.