Python 导入带有外键和SQLAlchemy的装置?
我一直在尝试使用fixture将测试数据集加载到我的Pylons/PostgreSQL应用程序中。这非常有效,但如果外键引用自动递增id字段,则无法正确创建外键 我的固定装置如下所示:Python 导入带有外键和SQLAlchemy的装置?,python,postgresql,sqlalchemy,pylons,fixture,Python,Postgresql,Sqlalchemy,Pylons,Fixture,我一直在尝试使用fixture将测试数据集加载到我的Pylons/PostgreSQL应用程序中。这非常有效,但如果外键引用自动递增id字段,则无法正确创建外键 我的固定装置如下所示: class AuthorsData(DataSet): class frank_herbert: first_name = "Frank" last_name = "Herbert" class BooksData(DataSet): class dune:
class AuthorsData(DataSet):
class frank_herbert:
first_name = "Frank"
last_name = "Herbert"
class BooksData(DataSet):
class dune:
title = "Dune"
author_id = AuthorsData.frank_herbert.ref('id')
模型:
t_authors = sa.Table("authors", meta.metadata,
sa.Column("id", sa.types.Integer, primary_key=True),
sa.Column("first_name", sa.types.String(100)),
sa.Column("last_name", sa.types.String(100)),
)
t_books = sa.Table("books", meta.metadata,
sa.Column("id", sa.types.Integer, primary_key=True),
sa.Column("title", sa.types.String(100)),
sa.Column("author_id", sa.types.Integer, sa.ForeignKey('authors.id'))
)
运行“paster setup app development.ini”时,SQLAlchemey将FK值报告为“无”,因此显然找不到它:
15:24:27,284 INFO [sqlalchemy.engine.base.Engine.0x...9f50]
CREATE TABLE authors (
id SERIAL NOT NULL,
first_name VARCHAR(100),
last_name VARCHAR(100),
PRIMARY KEY (id)
)
15:24:27,284 INFO [sqlalchemy.engine.base.Engine.0x...9f50] {}
15:24:27,291 INFO [sqlalchemy.engine.base.Engine.0x...9f50] COMMIT
15:24:27,292 INFO [sqlalchemy.engine.base.Engine.0x...9f50]
CREATE TABLE books (
id SERIAL NOT NULL,
title VARCHAR(100),
author_id INTEGER,
PRIMARY KEY (id),
FOREIGN KEY(author_id) REFERENCES authors (id)
)
15:24:27,293 INFO [sqlalchemy.engine.base.Engine.0x...9f50] {}
15:24:27,300 INFO [sqlalchemy.engine.base.Engine.0x...9f50] COMMIT
15:24:27,301 INFO [blog.websetup] Inserting initial data
15:24:27,302 INFO [sqlalchemy.engine.base.Engine.0x...9f50] BEGIN
15:24:27,309 INFO [sqlalchemy.engine.base.Engine.0x...9f50] INSERT INTO authors (first_name, last_name) VALUES (%(first_name)s, %(last_name)s) RETURNING authors.id
15:24:27,309 INFO [sqlalchemy.engine.base.Engine.0x...9f50] {'first_name': 'Frank', 'last_name': 'Herbert'}
15:24:27,320 INFO [sqlalchemy.engine.base.Engine.0x...9f50] INSERT INTO books (title, author_id) VALUES (%(title)s, %(author_id)s) RETURNING books.id
15:24:27,320 INFO [sqlalchemy.engine.base.Engine.0x...9f50] {'author_id': None, 'title': 'Dune'}
15:24:27,322 INFO [sqlalchemy.engine.base.Engine.0x...9f50] COMMIT
15:24:27,323 INFO [blog.websetup] Done
fixture文档实际上警告这可能是一个问题:
但是,在某些情况下,您可能需要引用一个在加载之前没有值的属性,如序列ID列。(请注意,在使用会话时,SQLAlchemy数据层不支持这一点。)
这是否意味着SQLAlchemy不支持这一点?或者是否可以在不使用SA“会话”的情况下加载数据?其他人是如何处理这个问题的?在SQLAlchemy中,SQL表达式层不支持引用尚未插入的行,因为它没有意义:所有查询都显式执行。ORM层确实支持对新对象的引用,它甚至使用工作单元模式来正确组织插入顺序。为了解决这个问题,夹具使用
ref()
方法。但请注意,在SQL表达式层中,您(fixture)执行语句,所以SQLAlchemy没有机会对它们重新排序。因此,如果您试图在该书引用的作者之前存储该书,author\u id
将不可用。你确定你的装置是按正确的顺序组织的(传递给data()
method)?你不能说author=AuthorsData.frank\u herbert
而不是直接指定作者id
除此之外,在插入AuthorsData后调用
meta.Session.flush()
可能会强制id属性获取值?这就是我在测试中需要分配ID时使用的方法(我不使用fixture)。我通过定义orm.relation
来解决这个问题,如下所示:
class BooksData(DataSet):
class dune:
title = "Dune"
author = AuthorsData.frank_herbert
mapper(Book, books, properties={
'author': relation(Author)
})
是-请参阅上面我更新的SA日志。我甚至尝试在完全独立的data()语句中插入作者和书籍数据。。。不走运