【问题标题】:Error: trying to redefine a primary key as non-primary key错误:尝试将主键重新定义为非主键
【发布时间】:2017-11-05 22:00:17
【问题描述】:

我正在使用dataset 库尝试将 postgres 数据库备份到 sqlite 文件中。我运行的代码如下:

local_db = "sqlite:///backup_file.db"

with dataset.connect(local_db) as save_to:
    with dataset.connect(postgres_db) as download_from:

        for row in download_from['outlook']:
            save_to['outlook'].insert(row)

如果我打印表格的一行,它看起来像这样:

OrderedDict([
    ('id', 4400),
    ('first_sighting', '2014-08-31'),
    ('route', None),
    ('sighted_by', None),
    ('date', None)
])

但是,当我到达save_to['outlook'].insert(row) 行时,我收到以下堆栈跟踪错误:

Traceback (most recent call last):
  File "/home/anton/Development/Python/TTC/backup_db.py", line 25, in <module>
    save_to['outlook'].insert(dict(row))
  File "/home/anton/.virtualenvs/flexity/lib/python3.6/site-packages/dataset/table.py", line 79, in insert
    row = self._sync_columns(row, ensure, types=types)
  File "/home/anton/.virtualenvs/flexity/lib/python3.6/site-packages/dataset/table.py", line 278, in _sync_columns
    self._sync_table(sync_columns)
  File "/home/anton/.virtualenvs/flexity/lib/python3.6/site-packages/dataset/table.py", line 245, in _sync_table
    self._table.append_column(column)
  File "/home/anton/.virtualenvs/flexity/lib/python3.6/site-packages/sqlalchemy/sql/schema.py", line 681, in append_column
    column._set_parent_with_dispatch(self)
  File "/home/anton/.virtualenvs/flexity/lib/python3.6/site-packages/sqlalchemy/sql/base.py", line 431, in _set_parent_with_dispatch
    self._set_parent(parent)
  File "/home/anton/.virtualenvs/flexity/lib/python3.6/site-packages/sqlalchemy/sql/schema.py", line 1344, in _set_parent
    self.key, table.fullname))
sqlalchemy.exc.ArgumentError: Trying to redefine primary-key column 'id' as a non-primary-key column on table 'outlook'

关于我做错了什么有什么想法吗?我在 python 2.7.14 和 3.6.3 中试过这个

【问题讨论】:

  • 第二次插入是否失败?
  • 什么是“非主键”?

标签: python postgresql sqlite python-dataset


【解决方案1】:

我想通了!所以,诀窍是默认情况下database 库使用自动递增整数主键生成表。但是,我的数据已经有一个“id”列。为了避免这个问题,我应该在尝试添加行之前定义我的表,并在没有主键的情况下定义它,如下所示:

with dataset.connect(local_db) as save_to:
    with dataset.connect(postgres_db) as download_from:

        table_to_save_to = save_to.create_table('outlook', primary_id=False)

        for row in download_from['outlook']:
            table_to_save_to.insert(row)

通过.create_table(table_name, primary_key=False),我可以确保我可以将自己的 id 值插入到表中。

我通过reading the docs找到了这个解决方案。

【讨论】:

    【解决方案2】:

    假设您有一个为“outlook”制作的架构和表,您是否制作了一个 PK 字段?是让 sqlite 决定哪个字段做 PK 字段吗?

    您尝试插入 id 两次非常重要。一次,sqlite 是插入自己,而 other 来自其他表记录。

    【讨论】:

    • 这是有道理的。我没有定义模式 - 应该由图书馆处理 - 但可能是图书馆认为我的数据中不会有“id”字段。
    猜你喜欢
    • 2014-09-06
    • 1970-01-01
    • 2016-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多