简体   繁体   English

如何为 sqlalchemy 中的主键列配置序列 object?

[英]How can I configure a sequence object for my primary key column in sqlalchemy?

I want MediaFolder class to have auto-generated id when adding to the database or initializing.我希望MediaFolder class 在添加到数据库或初始化时具有自动生成的id I've tried:我试过了:

from sqlalchemy import Column, String, BigInteger, ForeignKey, Sequence
from __init__ import Base


class MediaFolder(Base):
    __tablename__ = 'media_folder'

    seq = Sequence('id', start=20000000)
    id = Column(BigInteger, server_default=seq.next_value(), primary_key=True)

    name = Column(String, nullable=False)

    username = Column(String, nullable=False)

x = MediaFolder()
x.name = 'test seq'
x.username = 'test seq u'


from __init__ import db_session
db_session.add(x)
db_session.commit()

but when execute, I get:但是执行时,我得到:

Traceback (most recent call last):
  File "C:\Users\Krzysiek\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py", line 1249, in _execute_context
    cursor, statement, parameters, context
  File "C:\Users\Krzysiek\Anaconda3\lib\site-packages\sqlalchemy\engine\default.py", line 580, in do_execute
    cursor.execute(statement, parameters)
psycopg2.errors.NotNullViolation: null value in column "id" violates not-null constraint
DETAIL:  Failing row contains (null, test seq, test seq u, null).


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:/Users/Krzysiek/Desktop/praca/media_library/media/media_folder.py", line 29, in <module>
    db_session.commit()
  File "C:\Users\Krzysiek\Anaconda3\lib\site-packages\sqlalchemy\orm\scoping.py", line 162, in do
    return getattr(self.registry(), name)(*args, **kwargs)
  File "C:\Users\Krzysiek\Anaconda3\lib\site-packages\sqlalchemy\orm\session.py", line 1027, in commit
    self.transaction.commit()
  File "C:\Users\Krzysiek\Anaconda3\lib\site-packages\sqlalchemy\orm\session.py", line 494, in commit
    self._prepare_impl()
  File "C:\Users\Krzysiek\Anaconda3\lib\site-packages\sqlalchemy\orm\session.py", line 473, in _prepare_impl
    self.session.flush()
  File "C:\Users\Krzysiek\Anaconda3\lib\site-packages\sqlalchemy\orm\session.py", line 2470, in flush
    self._flush(objects)
  File "C:\Users\Krzysiek\Anaconda3\lib\site-packages\sqlalchemy\orm\session.py", line 2608, in _flush
    transaction.rollback(_capture_exception=True)
  File "C:\Users\Krzysiek\Anaconda3\lib\site-packages\sqlalchemy\util\langhelpers.py", line 68, in __exit__
    compat.reraise(exc_type, exc_value, exc_tb)
  File "C:\Users\Krzysiek\Anaconda3\lib\site-packages\sqlalchemy\util\compat.py", line 153, in reraise
    raise value
  File "C:\Users\Krzysiek\Anaconda3\lib\site-packages\sqlalchemy\orm\session.py", line 2568, in _flush
    flush_context.execute()
  File "C:\Users\Krzysiek\Anaconda3\lib\site-packages\sqlalchemy\orm\unitofwork.py", line 422, in execute
    rec.execute(self)
  File "C:\Users\Krzysiek\Anaconda3\lib\site-packages\sqlalchemy\orm\unitofwork.py", line 589, in execute
    uow,
  File "C:\Users\Krzysiek\Anaconda3\lib\site-packages\sqlalchemy\orm\persistence.py", line 245, in save_obj
    insert,
  File "C:\Users\Krzysiek\Anaconda3\lib\site-packages\sqlalchemy\orm\persistence.py", line 1137, in _emit_insert_statements
    statement, params
  File "C:\Users\Krzysiek\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py", line 988, in execute
    return meth(self, multiparams, params)
  File "C:\Users\Krzysiek\Anaconda3\lib\site-packages\sqlalchemy\sql\elements.py", line 287, in _execute_on_connection
    return connection._execute_clauseelement(self, multiparams, params)
  File "C:\Users\Krzysiek\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py", line 1107, in _execute_clauseelement
    distilled_params,
  File "C:\Users\Krzysiek\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py", line 1253, in _execute_context
    e, statement, parameters, cursor, context
  File "C:\Users\Krzysiek\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py", line 1473, in _handle_dbapi_exception
    util.raise_from_cause(sqlalchemy_exception, exc_info)
  File "C:\Users\Krzysiek\Anaconda3\lib\site-packages\sqlalchemy\util\compat.py", line 398, in raise_from_cause
    reraise(type(exception), exception, tb=exc_tb, cause=cause)
  File "C:\Users\Krzysiek\Anaconda3\lib\site-packages\sqlalchemy\util\compat.py", line 152, in reraise
    raise value.with_traceback(tb)
  File "C:\Users\Krzysiek\Anaconda3\lib\site-packages\sqlalchemy\engine\base.py", line 1249, in _execute_context
    cursor, statement, parameters, context
  File "C:\Users\Krzysiek\Anaconda3\lib\site-packages\sqlalchemy\engine\default.py", line 580, in do_execute
    cursor.execute(statement, parameters)
sqlalchemy.exc.IntegrityError: (psycopg2.errors.NotNullViolation) null value in column "id" violates not-null constraint
DETAIL:  Failing row contains (null, test seq, test seq u, null).

[SQL: INSERT INTO media_folder (name, username) VALUES (%(name)s, %(username)s) RETURNING media_folder.id]
[parameters: {'name': 'test seq', 'username': 'test seq u'}]
(Background on this error at: http://sqlalche.me/e/gkpj)

Basically id returns null.基本上id返回 null。 I've tried everything to solve this or to understand the sequence.我已经尝试了一切来解决这个问题或理解这个顺序。 How can I have the id value generated properly?如何正确生成id值? Or maybe is there another way to auto-generate values in sqlalchemy?或者也许还有另一种方法可以在 sqlalchemy 中自动生成值?

You can create the sequence as part of the id column declaration.您可以将序列创建为 id 列声明的一部分。

class MediaFolder(Base):
    __tablename__ = 'media_folder'

    seq = Sequence('id', start=20000000)
    id = Column(BigInteger, Sequence('media_folder_id', start=20000000), primary_key=True)

    name = Column(String, nullable=False)
    username = Column(String, nullable=False)

This is what is in the database after the code is executed:这是代码执行后数据库中的内容:

test=# \d media_folder_id
                        Sequence "public.media_folder_id"
  Type  |  Start   | Minimum |       Maximum       | Increment | Cycles? | Cache 
--------+----------+---------+---------------------+-----------+---------+-------
 bigint | 20000000 |       1 | 9223372036854775807 |         1 | no      |     1

test=# SELECT * FROM media_folder;
    id    |   name   |  username  
----------+----------+------------
 20000000 | test seq | test seq u

(it's a good idea to give the sequence a more unique name than just "id"). (给序列一个比“id”更独特的名称是个好主意)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 sqlalchemy:如何将其他表的对象与主键关联? - sqlalchemy: How can I associate object of other table with primary key? 如何创建一个sqlalchemy列,其默认值等于主键? - How can I create a sqlalchemy column whose default is to be equal to the primary key? 如何查询 sqlalchemy 中没有主键的表? - How can I query over a table without primary key in sqlalchemy? 如何使用新主键克隆 SQLAlchemy object - How to clone a SQLAlchemy object with new primary key 如何配置 MYSQL DB 以接受 NULL 作为 INSERT 语句中的主键,然后生成唯一的主键 - How can I configure MYSQL DB to accept NULL for primary key in the INSERT statement and then generate unique primary key SQLAlchemy - 我如何 map 将数据库值(列)转换为我的值 object ZA2F2ED4F8DC40AB66 - SQLAlchemy - How can I map a database value(column) to my value object class? 使用python sqlalchemy,如何定义多列主键 - with python sqlalchemy, how do define multiple-column primary key 如何使用SQLAlchemy创建一个不是主键的标识列? - How to create an identity column not being a primary key with SQLAlchemy? 我应该为我的sqlalchemy模型使用代理键(id = 1)还是自然主键(tag =&#39;sqlalchemy&#39;)? - Should I use a surrogate key (id= 1) or natural primary key (tag='sqlalchemy') for my sqlalchemy model? 如何使用列 object 获取/设置 SqlAlchemy 查询值 - How can I get/set an SqlAlchemy query value with the Column object
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM