我有一個包含點和對象概念的數據庫。對象與一對一關係中的單個點相關聯。一次只能有一個對象與一個點關聯,這是我通過唯一性約束強制執行的。允許引用不存在的記錄的SQLAlchemey中的複合外鍵
但是,我總是想說,對象只能與存在的點關聯,但我很難看到如何實現這一點。
在我進一步解釋,這裏是一些測試代碼,我有:
import sqlalchemy as sql
import sqlalchemy.orm as sqlorm
import sqlalchemy.ext.declarative
import os
debug = True
db_file = "/".join([os.getcwd() if __name__ == "__main__" else os.path.dirname(__file__), 'sqlite.db'])
engine_opts = {
'echo': debug
}
engine = sql.create_engine('sqlite:///{}'.format(db_file), **engine_opts)
Session = sqlorm.sessionmaker(bind=engine)
Base = sqlalchemy.ext.declarative.declarative_base()
class Point(Base):
__tablename__ = 'point'
x = sql.Column(sql.Integer, primary_key=True, nullable=False)
y = sql.Column(sql.Integer, primary_key=True, nullable=False)
def __repr__(self):
return self.__str__()
def __str__(self):
return "({x},{y})".format(x=self.x, y=self.y)
def __unicode__(self):
return self.__str__()
class Obj(Base):
__tablename__ = 'obj'
id = sql.Column(sql.Integer, primary_key=True)
x = sql.Column(sql.Integer)
y = sql.Column(sql.Integer)
__table_args__ = (
sql.ForeignKeyConstraint([x, y], [Point.x, Point.y]),
sql.UniqueConstraint(x, y, name='obj_coords'),
)
point = sqlorm.relationship("Point", backref=sqlorm.backref('obj', uselist=False))
def init_db():
Base.metadata.create_all(engine)
session = Session()
min_val = 0
max_val = 20
for x in range(min_val, max_val):
for y in range(min_val, max_val):
session.add(Point(x=x, y=y))
session.commit()
session.add(Obj(x=0, y=0))
session.add(Obj(x=10, y= 10))
session.add(Obj(x=-1, y=-1))
session.commit()
session.close()
def reinit_db():
Base.metadata.drop_all(engine)
init_db()
if __name__ == "__main__":
reinit_db()
我有Point
複合主鍵,我想對Obj
使用x
和y
作爲外鍵。
的backref
工程和唯一性約束意味着沒有2個OBJ文件可以佔用相同的觀點,但我的測試代碼允許我創建於不存在Point
(-1,-1)時,我想這是一個Obj
預防。
這是可能實現的,我該怎麼做呢?
對它進行排序,完美!是的,我目前正在開發SQLite,只是爲了方便起見,雖然我開始懷疑如果這樣的「陷阱」是否很方便 – chrisbunney