python - 无法从 SQLAlchemy 中的 psql-> sqlite3 create_all()
问题描述
我正在尝试将 PostgressSQL -> 转储到 -> SQLite3 及其所有数据。
主要思想是创建两个引擎,一个用于 PSQL,第二个用于 sqlite3。然后我reflect
在 sqlite 引擎上的 psql 引擎 - 并运行create_all()
但随后我收到以下错误
2019-07-18 11:41:47,660 INFO sqlalchemy.engine.base.Engine ()
2019-07-18 11:41:47,660 INFO sqlalchemy.engine.base.Engine ROLLBACK
Traceback (most recent call last):
... etc ...
sqlalchemy.exc.OperationalError: (pysqlite2.dbapi2.OperationalError) near "(": syntax error [SQL: u"\nCREATE TABLE table1 (\n\tcolumn_id INTEGER DEFAULT nextval('table1_id_seq'::regclass) NOT NULL, \n\t
(Background on this error at: http://sqlalche.me/e/e3q8)
这很有趣,因为 SQLAlchemy 生成了CREATE TABLE
- 确实如此。create table
问题是它何时执行sqlite3
然后sqlite3
将错误返回给 SQLAlchemy - 它不了解以下内容nextval
和::
是:
column_id INTEGER DEFAULT nextval('table1_id_seq'::regclass) NOT NULL,
column_name VARCHAR(15) DEFAULT 'no-name'::character varying,
就我个人而言,我什至不需要这些——因为 sqlite 将用作快照数据库,但我怎么能忽略它呢?或调整?
编辑 1- 使用特定型号
如果在代码中我写了这样的东西
class Table1(Base):
__table__ = Table('table1',
Base.metadata,
Column('column_id', Integer, primary_key=True),
Column('column_name', Text, default='no-name'),
autoload=True)
工作示例 - 但我正在尝试做同样的事情class Table1
from sqlalchemy import create_engine
from sqlalchemy import Table, Column, Integer, Text
from sqlalchemy.ext.declarative import declarative_base
def review_md_tables(metadata):
if not metadata.sorted_tables:
print "-> Tables not found"
return
for Table in metadata.sorted_tables:
print "->", Table.name
print "PSQL database"
psql_url = "postgress://..."
psql_engine = create_engine(psql_url, echo=False)
psql_base = declarative_base(bind=psql_engine)
review_md_tables(psql_base.metadata)
class Table1(psql_base):
__table__ = Table('table1',
pql_base.metadata,
Column('column_id', Integer, primary_key=True),
Column('column_name', Text, default='no-name'),
autoload=True)
review_md_tables(psql_base.metadata)
sqlite_url = "sqlite:////tmp/db.sqlite"
sqlite_enging = create_engine(sqlite_url, echo=False)
# Duplicate PSQL tables -> SQLite
psql_base.metadata.create_all(sqlite_enging)
问题是,我不想开始为数据库中的每个表编写类模型......有什么想法吗?
解决方案
除非有人有更好的主意,否则这是我迄今为止找到的解决方案 - 是server_default
从这些列中一一删除(我们可以使用default
SQLAlchemy 默认定义..
def remove_defaults_from_tables(metadata):
for Table in metadata.sorted_tables:
print "--> Adjusting table: ", Table.name
# Fixing PSQL unsupported DEFAULT & serial columns
# https://github.com/sqlalchemy/sqlalchemy/issues/525
# https://github.com/sqlalchemy/sqlalchemy/issues/1565
if Table.name in ["table1", "table2"]:
Table.c.id.server_default = None
所以这个函数应该在填充完所有之后metadata
使用Tables
# This doesn't require pre-defined Models -
# BUT they will also load those special PSQL variables which SQLAlchemy
# can't determine later during the `create_all`
Base.metadata.reflect(bind=my_psql_engine, only=["table1", "table2"])
remove_defaults_from_tables(Base.metadata)
推荐阅读
- ios - 在不拉伸图像的情况下增加 UIButton Tap 区域
- ios - 根据选择和默认状态设置按钮图像
- excel - 运行时错误“1004”无法设置工作表类的可见属性
- javascript - 放大/缩小谷歌地图时更改信息窗口的位置
- php - 如何在 laravel 中使用单表继承获取数据
- database - H2 数据库:如何列出所有视图?
- java - Java 11:通过 Shebang 执行源文件不起作用
- unix - unix 从文件中提取数据
- php - 如何通过 LAN 网络从另一台计算机访问 localhost (xampp) 服务器
- python-3.x - 用 2 个 csv 文件循环困难