当前位置: 首页 > 面试题库 >

删除未在sqlalchemy中级联到表

潘弘博
2023-03-14
问题内容

我正在开发使用sqlalchemy 0.6的现有应用程序的扩展。

该应用程序具有以非声明方式创建的sqlalchemy表。我正在尝试在扩展程序中创建一个新表,该表的外键列指向应用程序数据库中主表的主键,并且以声明方式创建它。

这一切都很好,加载扩展程序后就创建了表,一点也没有抱怨。我的表将打印出来,并演示已经添加了新行。我想要并认为可能的(但不知道,因为我从未使用过sql或任何其他数据库)是在删除应用程序主表中具有相应外键的行时删除表中的相应行。

到目前为止,已经尝试了许多排列,但没有任何效果。我认为设置了backref并定义了具有级联的delete的关系,应该不会有问题。因为新表是在扩展名中定义的,扩展名应该只是插件,所以我根本不想编辑主应用程序中的代码,至少这是我的目标。但是,我遇到的问题之一是我要引用的主应用程序表,在其类中没有定义成员变量,未在其映射器中声明其主键并且仅在表中声明了主键。
。这使得很难创建一个Relation(ship)子句,该子句的第一个自变量必须是类或映射器(在这种情况下,都没有声明主键)。有什么办法可以做到这一点?

ps-这是我正在使用的一些代码。LocalFile是声明性类。所有连接细节均由主应用程序处理。

    if not self.LocalFile.__table__.exists(bind=Engine):
        self.LocalFile__table__.create(bind=Engine)

这是LocalFile类-基类是声明性基类,在构造函数中传递了bind = Engine:

   class LocalFile(Base):
    __tablename__ = 'local_file'
    _id = Column(Integer, Sequence('local_file_sequence', start=1, increment=1), primary_key=True)
    _filename = Column(String(50), nullable=False)
    _filepath = Column(String(128), nullable=False)
    _movieid = Column(Integer, ForeignKey(db.tables.movies.c.movie_id, onupdate='CASCADE', ondelete='CASCADE'))
    #movies = relation(db.Movie, backref="local_file", cascade="all")

    @property
    def filename(self):
        return self._filename

    @filename.setter
    def filename(self, filename):
        self._filename = filename

    @property
    def filepath(self):
        return self._filepath

    @filepath.setter
    def filepath(self, filepath):
        self._filepath = filepath

    @property
    def movieid(self):
        return self._movieid

    @movieid.setter
    def movieid(self, movieid):
        self._movieid = movieid

    @property
    def id(self):
        return self._id

    @id.setter
    def id(self, id):
        self._id = id

    filename = synonym('_filename', descriptor=filename)
    movieid = synonym('_movieid', descriptor=movieid)
    filepath = synonym('_filepath', descriptor=filepath)
    id = synonym('_id', descriptor=id)

    def __init__(self, filename, filepath, movieid):
        self._filename = filename
        self._filepath = filepath
        self._movieid = movieid

    def __repr__(self):
        return "<User('%s','%s', '%s')>" % (self.filename, self.filepath, self.movieid)

编辑:

后端是sqlite3。下面是使用echo命令生成的表的创建代码(感谢您指出这一点,它非常有用-
我已经怀疑现有应用程序生成的SQL远远超出了必要)。报告的sql表创建之后是删除行时生成的代码。我个人看不到任何引用本地文件表中可能删除行的语句,但是我目前几乎不了解sql。谢谢。

     2011-12-29 16:29:18,530 INFO sqlalchemy.engine.base.Engine.0x...0650 
     CREATE TABLE local_file (
_id INTEGER NOT NULL, 
_filename VARCHAR(50) NOT NULL, 
_filepath VARCHAR(128) NOT NULL, 
_movieid INTEGER, 
PRIMARY KEY (_id), 
FOREIGN KEY(_movieid) REFERENCES movies (movie_id) ON DELETE CASCADE ON UPDATE CASCADE

    2011-12-29T16:29:18: I: sqlalchemy.engine.base.Engine.0x...0650(base:1387): 
    CREATE TABLE local_file (
_id INTEGER NOT NULL, 
_filename VARCHAR(50) NOT NULL, 
_filepath VARCHAR(128) NOT NULL, 
_movieid INTEGER, 
PRIMARY KEY (_id), 
FOREIGN KEY(_movieid) REFERENCES movies (movie_id) ON DELETE CASCADE ON UPDATE CASCADE

2011-12-29 16:29:18,534 INFO sqlalchemy.engine.base.Engine.0x...0650 ()
2011-12-29T16:29:18: I: sqlalchemy.engine.base.Engine.0x...0650(base:1388): ()
2011-12-29 16:29:18,643 INFO sqlalchemy.engine.base.Engine.0x...0650 COMMIT
2011-12-29T16:29:18: I: sqlalchemy.engine.base.Engine.0x...0650(base:1095): COMMIT

表中的行会为两个表生成以下内容:

本地文件表:(,u‘310 To Yuma’)(,u’Ravenous’)

现有应用中的电影表:(,u’IMDb-3:10 to Yuma’)(,u’Ravenous’)

删除行时的代码太长,以至于我无法在此处包括它(大约200行-删除一行不是太多吗?),但是它没有引用删除localfile表中的行。有如下语句:

   2011-12-29 17:09:17,141 INFO sqlalchemy.engine.base.Engine.0x...0650 UPDATE movies SET   poster_md5=?, updated=? WHERE movies.movie_id = ?
   2011-12-29T17:09:17: I: sqlalchemy.engine.base.Engine.0x...0650(base:1387): UPDATE movies SET poster_md5=?, updated=? WHERE movies.movie_id = ?
   2011-12-29 17:09:17,142 INFO sqlalchemy.engine.base.Engine.0x...0650 (None, '2011-12-29 17:09:17.141019', 2)
   2011-12-29T17:09:17: I: sqlalchemy.engine.base.Engine.0x...0650(base:1388): (None, '2011-12-29 17:09:17.141019', 2)
   2011-12-29 17:09:17,150 INFO sqlalchemy.engine.base.Engine.0x...0650 DELETE FROM posters WHERE posters.md5sum = ?
   2011-12-29T17:09:17: I: sqlalchemy.engine.base.Engine.0x...0650(base:1387): DELETE FROM posters WHERE posters.md5sum = ?
   2011-12-29 17:09:17,157 INFO sqlalchemy.engine.base.Engine.0x...0650 (u'083841e14b8bb9ea166ea4b2b976f03d',)

问题答案:

在SQLite中,您必须显式打开对外键的支持,否则它将忽略任何与外键相关的SQL。

engine = create_engine(database_url)

def on_connect(conn, record):
    conn.execute('pragma foreign_keys=ON')

from sqlalchemy import event
event.listen(engine, 'connect', on_connect)


 类似资料:
  • 问题内容: 我必须缺少SQLAlchemy的层叠选项的琐碎内容,因为我无法获得简单的层叠删除来正确操作-如果删除了父元素,则子对象将使用外键保留。 我在这里放了一个简洁的测试用例: 输出: 父母与子女之间存在简单的一对多关系。该脚本创建一个父级,添加3个子级,然后提交。接下来,它删除父级,但子级仍然存在。为什么?如何使孩子级联删除? 问题答案: 问题是sqlalchemy认为是父级的,因为这是您定

  • 问题内容: 我的模型与模型有关系。我已指定该关系应级联删除操作。但是,当我查询和删除用户时,出现一个错误,指出仍在引用地址行。如何删除用户和地址? 问题答案: 你有以下… 请注意,在“过滤器”之后,您仍然返回Query对象。因此,当您调用时,您正在调用Query对象(而不是User对象)。这意味着您正在执行批量删除(尽管可能只删除了一行) 您正在使用的方法的文档说… 该方法不提供Python中的级

  • 我正在尝试创建具有一对一关系的域对象。A 是父母,B 是孩子。 我尝试了许多不同的方法来将删除从 A 级联到 B,但是当我查看数据库创建时,它没有设置 ON DELETE CASCADE。 有人能看到我做错了什么吗 答: 我知道CascadeType.ALL或孤儿移除应该有效果,但他们没有。 B: 有人能明白为什么它不级联删除吗?

  • 主要内容:JPA级联删除示例,输出结果级联移除用于指定如果父实体被移除,则其所有相关实体也将被移除。 以下语法用于执行级联删除操作 - JPA级联删除示例 在这个例子中,我们将创建两个相互关联的实体类,但要建立它们之间的依赖关系,我们将执行级联操作。 这个例子包含以下步骤 - 第1步: 在包下创建一个名为的实体类,其中包含属性:,,以及标记为级联规范的类型的对象。 文件: StudentEntity.java - 第2步: 在包下创建

  • 级联删除通常被用作数据库术语,用来描述删除一个数据行时自动删除关联的数据行的特征。EF Core 实现了一些不同的删除行为,并且允许对关联关系的删除行为进行配置。EF Core 还实现了相关的惯例,它会基于关系的必要性为每个关系配置有用的默认删除行为。 删除行为 删除行为是在 DeleteBehavior 枚举中定义的,可以将它传递给 OnDelete 流式 API 来控制主实体/父实体的删除是否

  • 问题内容: 如果我的数据库中有一个简单的User表,而有一个以User.id作为外键的简单Item表,则: 如果将用户从表中删除,我需要先删除所有相关项,以免破坏参照完整性约束。这很容易做到 但是,如果我也有引用用户的集合,还有一个将项目收集到集合中的表,那么我很麻烦,即以下附加代码不起作用。 该错误表明“可能导致循环或多个级联路径”。我认为推荐的解决方法是 重新设计表格,但是我看不到如何做。或者