Я разрабатываю расширение для существующего приложения, которое использует sqlalchemy 0.6.
В приложении есть таблицы sqlalchemy, созданные не декларативным способом. Я пытаюсь создать в своем расширении новую таблицу со столбцом внешнего ключа, указывающим на первичный ключ главной таблицы в базе данных приложения, и создаю ее декларативно.
Это все работает нормально, с таблицей, созданной после загрузки расширения, и без каких-либо жалоб. Моя таблица распечатывает и демонстрирует, что новые строки были добавлены нормально.
То, что я хочу и думаю, возможно (но не знаю, поскольку я никогда не использовал sql или любую другую базу данных) для соответствующей строки в моей таблице, которая будет удалена при удалении строки в основной таблице приложения с соответствующим внешним ключом .
До сих пор, и со многими попытками перестановок ничего не работало. Я думал, что с набором обратных ссылок и с отношением, определенным каскадным удалением, проблем быть не должно. Поскольку новая таблица определена в расширении, которое должно быть просто подключаемым, я вообще не хочу редактировать код в основном приложении, по крайней мере, это моя цель. Одна из проблем, с которой я столкнулся, заключается в том, что главная таблица приложения, на которую я хочу сослаться, не имеет переменных-членов, определенных в своем классе, не объявляет свой первичный ключ в своем преобразователе и имеет только первичный ключ, объявленный в таблице. , Это затрудняет создание предложения отношения (ship), первым аргументом которого должен быть класс или преобразователь (в этом случае ни у одного из которых не объявлен первичный ключ).
Есть ли способ достичь этого?
ps - вот код, который я использую. LocalFile - это декларативный класс. Все детали подключения рассматриваются основным приложением.
if not self.LocalFile.__table__.exists(bind=Engine):
self.LocalFile__table__.create(bind=Engine)
Вот класс LocalFile - Base - это декларативный базовый класс с 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)
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 к Юме)
(, 'Ravenous')
таблица фильмов в существующем приложении:
(, u'IMDb - 3:10 Юме ')
(, ты, Райн *)
Код при удалении строки настолько длинный, что я не могу его сюда включить (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',)