我正尝试将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将用作快照数据库,但是如何忽略呢?或进行调整?
如果在代码中,我写这样的东西
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)
问题是,我不想开始为数据库中的每个表编写类模型……有什么想法吗?
答案 0 :(得分:0)
除非有人有更好的主意,否则这是我到目前为止找到的解决方案-逐一删除这些列中的server_default
(我们可以使用default
定义SQLAlchemy默认值.. < / p>
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)