Я разрабатываю расширение для существующего приложения, которое использует sqlalchemy 0.6.delete not cascaded to table in sqlalchemy
Приложение имеет таблицы sqlalchemy, созданные не декларативным способом. Я пытаюсь создать в своем расширении новую таблицу с колонкой внешнего ключа, указывающую на первичный ключ основной таблицы в базе данных приложения, и я создаю ее декларативно.
Все это работает отлично, с таблицей, созданной после загрузки расширения, и без каких-либо претензий. Моя таблица распечатывает и демонстрирует, что новые строки были добавлены в порядке. Я хочу и думаю, что возможно (но не знаю, как я никогда не использовал sql или любую другую базу данных) для того, чтобы соответствующая строка в моей таблице была удалена, когда строка в главной таблице приложения с соответствующим внешним ключом удален.
До сих пор и при многих перестановках, которые были опробованы, ничего не сработало. Я думал, что с настройкой backref и с отношением, определенным с каскадом удаления, не должно быть проблем. Поскольку новая таблица определена в расширении, которое должно быть просто плагином, я не хочу вообще редактировать код в главном приложении, по крайней мере, это моя цель. Одна из проблем, которые у меня есть, состоит в том, что основная таблица приложений, которую я хочу ссылаться, не имеет переменных-членов, определенных в ее классе, не объявляет ее первичный ключ в своем картографе и только имеет первичный ключ, объявленный в таблице , Это затрудняет создание предложения отношения (корабля), первым аргументом которого должен быть класс или картограф (в этом случае ни один из них не объявит первичный ключ). Есть ли способ достичь этого?
ps - вот некоторые из кода, который я использую. LocalFile - это декларативный класс. Все сведения о подключении позаботятся по основному приложению.
if not self.LocalFile.__table__.exists(bind=Engine):
self.LocalFile__table__.create(bind=Engine)
Вот класс лок_файла - Base декларативный базовый класс с привязкой = 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)
Edit:
Бэкэнда является 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
для строки в таблице производит следующее для двух таблиц:
локального файла таблицы: (, и»310 To Yuma ') (, u' Ravenous ')
таблица кино в существующем приложении: (, u'IMDb - 3:10 на Юму «) (, u'Ravenous»)
код при удалении строки так долго, что я не могу включить он здесь (200 строк или около того - разве это не слишком много для удаления одной строки?), но он не ссылается на удаление строки в таблице локального файла. Есть утверждения, как:
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',)
Не могли бы вы повернуть 'echo = True', убедиться, что таблица' local_file' не существует, и запустите свой код и проверьте/опубликуйте 'SQL', сгенерированную для создания таблицы. Также просьба упомянуть бэкэнд БД, который вы используете. – van
эй ван, только что сделал, что -тобы на главной записи включить код. Бэкэнд - sqlite3. Благодаря! –
только для информации: если вы заметили, вы увидите, что каждый оператор записывается дважды. это происходит, когда у вас есть echo = True, а также настраивает ведение журнала для пакетов sqlalchemy явно ... – van