Wenn ich Ihren Code ausführen wie geschrieben, es funktioniert nicht:
Traceback (most recent call last):
File "so4.py", line 26, in <module>
session.commit()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sqlalchemy/orm/session.py", line 906, in commit
self.transaction.commit()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sqlalchemy/orm/session.py", line 461, in commit
self._prepare_impl()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sqlalchemy/orm/session.py", line 441, in _prepare_impl
self.session.flush()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sqlalchemy/orm/session.py", line 2177, in flush
self._flush(objects)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sqlalchemy/orm/session.py", line 2297, in _flush
transaction.rollback(_capture_exception=True)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sqlalchemy/util/langhelpers.py", line 66, in __exit__
compat.reraise(exc_type, exc_value, exc_tb)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sqlalchemy/util/compat.py", line 187, in reraise
raise value
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sqlalchemy/orm/session.py", line 2261, in _flush
flush_context.execute()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sqlalchemy/orm/unitofwork.py", line 389, in execute
rec.execute(self)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sqlalchemy/orm/unitofwork.py", line 548, in execute
uow
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sqlalchemy/orm/persistence.py", line 181, in save_obj
mapper, table, insert)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sqlalchemy/orm/persistence.py", line 835, in _emit_insert_statements
execute(statement, params)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 945, in execute
return meth(self, multiparams, params)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sqlalchemy/sql/elements.py", line 263, in _execute_on_connection
return connection._execute_clauseelement(self, multiparams, params)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1053, in _execute_clauseelement
compiled_sql, distilled_params
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1189, in _execute_context
context)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1402, in _handle_dbapi_exception
exc_info
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sqlalchemy/util/compat.py", line 203, in raise_from_cause
reraise(type(exception), exception, tb=exc_tb, cause=cause)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sqlalchemy/util/compat.py", line 186, in reraise
raise value.with_traceback(tb)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1182, in _execute_context
context)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/sqlalchemy/engine/default.py", line 470, in do_execute
cursor.execute(statement, parameters)
sqlalchemy.exc.IntegrityError: (sqlite3.IntegrityError) UNIQUE constraint failed: countries.name [SQL: 'INSERT INTO countries (name) VALUES (?)'] [parameters: ('Malta',)]
Die eindeutige Einschränkung Teil der Tabelle ist, nicht unbedingt das Modell. Wenn ich die Datenbankerstellung zuerst ohne es ausführen, dann führe deinen Code aus, ich bekomme keine Probleme.
Für eine kompliziertere Tabelle möchten Sie ein Migrations-Tool wie Alembic verwenden, aber Sie können dies selbst tun (Sie können es in einem Skript tun, aber ich mache nur zwei, um es zu behalten) einfach, sorry, wenn das nicht pythonic ist.
from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
Base = declarative_base()
class Country(Base):
__tablename__ = 'countries'
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(64), unique=True, nullable=False, index=True)
class TempCountry(Base):
__tablename__ = 'temp_countries'
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(64), nullable=False, index=True)
engine = create_engine('sqlite:///countries_example.db')
Base.metadata.create_all(engine)
Base.metadata.bind = engine
DBSession = sessionmaker(bind=engine)
session = DBSession()
foreach country in session.query(Country).all():
if len(session.query(TempCountry).filter_by(name=country.name).all()) == 0:
temp_country = TempCountry(id=country.id, name=country.name)
session.add(temp_country)
session.commit()
Country.__table__.drop(engine)
session.commit()
gefolgt von
from sqlalchemy import Column, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
Base = declarative_base()
class Country(Base):
__tablename__ = 'countries'
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(64), unique=True, nullable=False, index=True)
class TempCountry(Base):
__tablename__ = 'temp_countries'
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(64), nullable=False, index=True)
engine = create_engine('sqlite:///countries_example.db')
Base.metadata.create_all(engine)
Base.metadata.bind = engine
DBSession = sessionmaker(bind=engine)
session = DBSession()
foreach temp_country in session.query(TempCountry).all():
country = Country(id=country.id, name=country.name)
session.add(country)
session.commit()
TempCountry.__table__.drop(engine)
session.commit()
Sie haben nicht die ID passieren, aber Sie können, wenn Sie brauchen für welchen Gründen auch immer, es zu halten Denken Sie auch daran zu begehen, bevor Sie den Tisch fallen lassen oder es wird nicht ganz richtig funktionieren
Haben Sie vielleicht die DB erstellt, bevor Sie Ihrem Modell 'unique = True' hinzugefügt haben? Wenn dies der Fall ist, müssen Sie das DB-Schema auf die eine oder andere Weise migrieren. –