假设我们有几个sqlalchemy模型用于目录:
Plane
现在出于导入/导出目的,我们希望将这些与外部ID相关联。因此对class PlaneID(Base):
issuer = Column(String(32), primary_key=True)
external_id = Column(String(16), primary_key=True)
plane_id = Column(Integer, ForeignKey(Plane.plane_id))
plane = relationship(Plane, backref='external_ids')
我们会写:
CarID
class CarID(ExternalID):
valid_from = Column(Date)
模型将以完全相同的方式定义。
自动执行此流程有哪些可能性?
也许我们可以使用mixin,factory,decorator或meta class。那么我们如何生成动态命名的Columns呢?能够根据需要向生成的模型添加更多列将是一件好事。例如:
public abstract class Character{
private double damage;
public Character();
public void setDamage(damage){
this.damage = damage;
}
public double getDamage(){return damage;}
}
public class Human extends Character{
public Human(){
damage = 10.00;
}
}
public abstract class Object extends Character{
public abstract String getDescription();
}
public class Sword extends Object{
Character character;
public Sword(Character character){
this.character = character;
updateDamage();
}
public String getDescription(){
// Something
}
public void updateDamage(){
character.setDamage(character.getDamage() + 2.00);
}
}
答案 0 :(得分:1)
您可以继承DeclarativeMeta
- declarative_base
函数中使用的元类:
from sqlalchemy.ext.declarative import DeclarativeMeta, declarative_base
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship
class ExternalObject(DeclarativeMeta):
def __new__(mcs, name, bases, attributes):
if 'issuer' not in attributes:
attributes['issuer'] = Column(String(32), primary_key=True)
if 'external_id' not in attributes:
attributes['external_id'] = Column(String(16), primary_key=True)
if name[-2:] == 'ID':
ext_cls_name = name[:-2]
attr_rel = ext_cls_name.lower()
attr_id = '%s_id' % attr_rel
if attr_rel in attributes or attr_id in attributes:
# Some code here in case 'car' or 'car_id' attribute is defined in new class
pass
attributes[attr_id] = Column(Integer, ForeignKey('%s.%s' % (ext_cls_name, attr_id)))
attributes[attr_rel] = relationship(ext_cls_name, backref='external_ids')
new_cls = super().__new__(mcs, name, bases, attributes)
return new_cls
ExternalID = declarative_base(metaclass=ExternalObject)
之后,您可以从ExternalID
创建子类,并添加您为CarID
所做的其他属性。