2010-06-02 64 views
3

我一直在试验使用夹具来将测试数据集加载到我的Pylons/PostgreSQL应用程序中。这很好,除非它引用一个自动增量id字段时无法正确创建外键。导入夹具与外键和SQLAlchemy?

我的灯具是这样的:

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')) 
    ) 

当运行 “贴纸设置 - 应用程序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 

夹具文档实际上警告这可能是一个问题:

“但是,在某些情况下,您可能需要引用一个属性,该属性在加载之前没有值,如序列ID列。 (请注意,这不是由SQLAlchemy的数据层支持使用会话时。)”

http://farmdev.com/projects/fixture/using-dataset.html#referencing-foreign-dataset-classes

,这是否意味着这只是不能与SQLAlchemy的支持?或者是有可能加载数据,而无需使用SA “会话”?其他人如何处理此问题?

回答

1

引用未插入的行不受SQLAlchemy中SQL表达式层的支持,因为它没有意义:所有查询都是显式执行的,ORM层确实支持对新对象的引用,它甚至使用工作模式来正确地组织插入顺序。为了解决这个问题,夹具使用了ref()的方法。 ,在SQL表达层中你(夹具)执行语句,所以SQLAlchemy没有机会对它们重新排序。因此,如果您尝试在所引用的作者之前存储书籍,则author_id不可用。你确定你的灯具是按照正确的顺序组织的吗(传递给data()方法)?

+0

是 - 请看我上面的更新日志SA。我甚至尝试在完全独立的数据()语句中插入作者和书籍数据...没有运气 – 2010-06-03 22:42:41

1

难道你不能说author = AuthorsData.frank_herbert而不是直接指定author_id

除此之外,也许在插入AuthorsData后调用meta.Session.flush()会强制id属性获取值?这就是我在测试中使用的ID,我需要分配ID(我不使用夹具)。

0

我定义orm.relation这样解决这个问题:

class BooksData(DataSet): 
    class dune: 
     title = "Dune" 
     author = AuthorsData.frank_herbert 


mapper(Book, books, properties={ 
    'author': relation(Author) 
})