简体   繁体   中英

Peewee circular foreign key dependencies exception

I'm trying to replicate Peewee example app using circular dependences as explained in the docs , despite the creator clearly states this is usually a bad idea. This is the code mainly copied from the docs:

from peewee import *

db = SqliteDatabase(None)

class BaseModel(Model):

class Meta:
    database = db

class User(BaseModel):
    username = CharField()
    # Tweet has not been defined yet so use the deferred reference.
    favorite_tweet = DeferredForeignKey('Tweet', null=True)

class Tweet(BaseModel):
    message = TextField()
    user = ForeignKeyField(User, backref='tweets')


db.init('twitter.db')
db.create_tables([User, Tweet])
User._schema.create_foreign_key(User.favorite_tweet) #Error
db.close()

I'm getting the an exception in the line commented with #Error. This line is needed, as explained in the docs:

When you call create_table we will again encounter the same issue. For this reason peewee will not automatically create a foreign key constraint for any deferred foreign keys.

To create the tables and the foreign-key constraint, you can use the SchemaManager.create_foreign_key() method to create the constraint after creating the tables.

This is the exception I get using Python 3.5.2:

Traceback (most recent call last):
  File "/usr/local/lib/python3.5/dist-packages/peewee.py", line 2653, in execute_sql
    cursor.execute(sql, params or ())
sqlite3.OperationalError: near "CONSTRAINT": syntax error

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "test3.py", line 23, in <module>
    User._schema.create_foreign_key(User.favorite_tweet)
  File "/usr/local/lib/python3.5/dist-packages/peewee.py", line 4930, in create_foreign_key
    self.database.execute(self._create_foreign_key(field))
  File "/usr/local/lib/python3.5/dist-packages/peewee.py", line 2666, in execute
    return self.execute_sql(sql, params, commit=commit)
  File "/usr/local/lib/python3.5/dist-packages/peewee.py", line 2660, in execute_sql
    self.commit()
  File "/usr/local/lib/python3.5/dist-packages/peewee.py", line 2451, in __exit__    reraise(new_type, new_type(*exc_args), traceback)
  File "/usr/local/lib/python3.5/dist-packages/peewee.py", line 178, in reraise
    raise value.with_traceback(tb)
  File "/usr/local/lib/python3.5/dist-packages/peewee.py", line 2653, in execute_sql
    cursor.execute(sql, params or ())
peewee.OperationalError: near "CONSTRAINT": syntax error

Sqlite does not support ALTER TABLE ADD CONSTRAINT -- so when you're using Sqlite you should omit the additional call to create_foreign_key().

There is a clear NOTE in the docs that says:

Because SQLite has limited support for altering tables, foreign-key constraints cannot be added to a table after it has been created.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM