使用 SqlAlchemy 和 Id 为 PostgreSQL 创建夹具数据

发布于 2024-11-29 05:51:00 字数 800 浏览 1 评论 0原文

我正在尝试将示例数据注入数据库,并创建了一个用于构建模型的固定文件,然后将实例合并到数据库中。我正在使用合并,因为我希望能够重新运行夹具,而无需重新创建数据库或截断所有表。

但是,在检查主键上的 Postgres 表的序列后,注入 10 个项目后,my_items_id_seq 显示以下内容:

       Sequence "public.my_items_id_seq"
    Column     |  Type   |        Value        
---------------+---------+---------------------
 sequence_name | name    | my_items_id_seq
 last_value    | bigint  | 1
 start_value   | bigint  | 1
 increment_by  | bigint  | 1
 max_value     | bigint  | 9223372036854775807
 min_value     | bigint  | 1
 cache_value   | bigint  | 1
 log_cnt       | bigint  | 0
 is_cycled     | boolean | f
 is_called     | boolean | t

合并夹具数据时如何增加 last_value?

[编辑]

这里突出的问题是,注入数据后,如果没有从 SqlAlchemy 获得 IntegrityError,我就无法将项目添加到数据库中。这是由于 PostgreSQL 尝试插入 id 为 1 的新实例。

I'm trying to inject sample data into my database, and have created a fixture file that builds my model, and then merges the instance into the database. I'm using merge, because I want to be able to re-run the fixture without recreating the database, or truncating all my tables.

However, upon inspection of my Postgres table's sequence on primary key, my_items_id_seq shows the following after injecting 10 items:

       Sequence "public.my_items_id_seq"
    Column     |  Type   |        Value        
---------------+---------+---------------------
 sequence_name | name    | my_items_id_seq
 last_value    | bigint  | 1
 start_value   | bigint  | 1
 increment_by  | bigint  | 1
 max_value     | bigint  | 9223372036854775807
 min_value     | bigint  | 1
 cache_value   | bigint  | 1
 log_cnt       | bigint  | 0
 is_cycled     | boolean | f
 is_called     | boolean | t

How can I increase the last_value as I merge in fixture data?

[edit]

The outstanding issue here is that after injecting the data, I can't add items to the database without getting an IntegrityError from SqlAlchemy. This is due to PostgreSQL trying to insert my new instance with id 1.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

雪花飘飘的天空 2024-12-06 05:51:00

答案的第一部分 是通过阅读有关 Django 和 PostgreSQL 的链接得出的,其中作者同样尝试使用索引提供迁移数据。

他的解决方案是获取最高的索引,然后执行以下查询:

alter sequence profile_billingaddress_id_seq restart with {id};

通过这个,我在 序列操作函数。执行此操作的首选方法是发出此查询:

select setval('my_items_id_seq', {id})

... 其中 {id} 显然是实数的占位符。我还注意到,last_value 只是 next_value 的最后一个响应。这很重要,因为使用 setval 而不是上面的 alter order 业务可以确保 nextval 提供未使用的索引。即当使用 setval 其中 id=10 时,nextval 将返回 11。当使用 alterequence 命令时,如果 id=10,则 nextval 也将返回 10。

The first part of the answer came through reading a link about Django and PostgreSQL, where the author similarly attempted to feed migration data with indexes.

His solution was to grab the highest index, and then execute the following query:

alter sequence profile_billingaddress_id_seq restart with {id};

Through this, I discovered the proper keyword to the PostgreSQL documentation on Sequence Manipulation Functions. The preferred way to do this is to issue this query:

select setval('my_items_id_seq', {id})

... where {id} is obviously a placeholder for a real integer. It also came to my attention that last_value is just the last response from next_value. This is important because using setval instead of the alter sequence business above ensures that nextval provides an unused index. I.e. when using setval where id=10, nextval will return 11. When using the alter sequence command, if id=10, then nextval will also return 10.

一人独醉 2024-12-06 05:51:00

我遇到了同样的问题,但正在尝试插入各种不同型号的固定装置。

以下来自 postgresql's wiki 的小片段将按照您想要的方式执行操作,但适用于模式中的每个序列。

SELECT 'SELECT SETVAL(' ||
   quote_literal(quote_ident(PGT.schemaname) || '.' || quote_ident(S.relname)) ||
   ', COALESCE(MAX(' ||quote_ident(C.attname)|| '), 1) ) FROM ' ||
   quote_ident(PGT.schemaname)|| '.'||quote_ident(T.relname)|| ';'
FROM pg_class AS S,
     pg_depend AS D,
     pg_class AS T,
     pg_attribute AS C,
     pg_tables AS PGT
WHERE S.relkind = 'S'
    AND S.oid = D.objid
    AND D.refobjid = T.oid
    AND D.refobjid = C.attrelid
    AND D.refobjsubid = C.attnum
    AND T.relname = PGT.tablename
ORDER BY S.relname;

它看起来有点神奇,但它的作用正是公认的答案所暗示的。

I had the same problem but was trying to insert fixtures for various different models.

The following little snippet from postgresql's wiki will do just what you want but for every sequence in your schema.

SELECT 'SELECT SETVAL(' ||
   quote_literal(quote_ident(PGT.schemaname) || '.' || quote_ident(S.relname)) ||
   ', COALESCE(MAX(' ||quote_ident(C.attname)|| '), 1) ) FROM ' ||
   quote_ident(PGT.schemaname)|| '.'||quote_ident(T.relname)|| ';'
FROM pg_class AS S,
     pg_depend AS D,
     pg_class AS T,
     pg_attribute AS C,
     pg_tables AS PGT
WHERE S.relkind = 'S'
    AND S.oid = D.objid
    AND D.refobjid = T.oid
    AND D.refobjid = C.attrelid
    AND D.refobjsubid = C.attnum
    AND T.relname = PGT.tablename
ORDER BY S.relname;

It looks a bit magical but does precisely what the accepted answer suggests.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文