I am trying to create a table on demand.
def create_host_table(name):
"""Create host server status table.
Arguments:
name (str): name of the host.
"""
class HostMachineStatus(Base):
__tablename__ = '{0}{1}{2}'.format(HOST_TABLE_PREFIX, name, HOST_TABLE_SUFFIX)
id = Column(Integer, primary_key=True)
status = Column(String(7)) # online or offline
datemodified = Column('datemodified', TIMESTAMP, server_default=text(
'CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'
)
)
datecreated= Column('datecreated', TIMESTAMP)
status_time_delta = ('status_time_delta', TIMESTAMP) # duration how long was online or offline.
table_name = HostMachineStatus.__tablename__
Base.metadata.create_all(engine, Base.metadata.tables[table_name],checkfirst=True)
but the above code throws error:
Traceback (most recent call last):
File "server_status.py", line 97, in <module>
main()
File "server_status.py", line 93, in main
create_host_table(host)
File "server_status.py", line 71, in create_host_table
Base.metadata.create_all(engine, Base.metadata.tables[table_name],checkfirst=True)
File "/home/rock64/.local/lib/python3.6/site-packages/sqlalchemy/sql/schema.py", line 4316, in create_all
ddl.SchemaGenerator, self, checkfirst=checkfirst, tables=tables
File "/home/rock64/.local/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 2049, in _run_visitor
conn._run_visitor(visitorcallable, element, **kwargs)
File "/home/rock64/.local/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1618, in _run_visitor
visitorcallable(self.dialect, self, **kwargs).traverse_single(element)
File "/home/rock64/.local/lib/python3.6/site-packages/sqlalchemy/sql/visitors.py", line 138, in traverse_single
return meth(obj, **kw)
File "/home/rock64/.local/lib/python3.6/site-packages/sqlalchemy/sql/ddl.py", line 754, in visit_metadata
[t for t in tables if self._can_create_table(t)]
TypeError: 'Table' object is not iterable
From the documentation (emphasis mine):
tables – Optional list of Table objects, which is a subset of the total tables in the MetaData (others are ignored).
So the issue is that you are passing a single table, not a list of tables. (The "is not iterable" in the error output is also a strong hint here.) Try this instead:
Base.metadata.create_all(engine, [Base.metadata.tables[table_name]], checkfirst=True)
Related
I'm using Python 3.9 and Django 3.2. I have this model with a ManyToMany field ...
class Account(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
active = models.BooleanField(default=True)
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
)
vendor = models.ForeignKey(Vendor, on_delete=models.DO_NOTHING)
crypto_currencies = models.ManyToManyField(CryptoCurrency)
def __init__(self, user, vendor, crypto_currencies_arr, max_transactions=DEFAULT_MAX_BUY_TRANSACTIONS):
self.crypto_currencies.set( set() )
for cc in crypto_currencies_arr:
self.crypto_currencies.add(cc)
super().__init__(
user=user,
vendor=vendor,
crypto_currencies=self.crypto_currencies
)
I'm having trouble figuring out how to initialize my many-to-many field with an array. The above results in this error
>>> account = Account(user=u, vendor=v, crypto_currencies_arr=[c])
Traceback (most recent call last):
File "<input>", line 1, in <module>
account = Account(user=u, vendor=v, crypto_currencies_arr=[c])
File "/Users/davea/Documents/workspace/cbapp/cbapp/models/account.py", line 47, in __init__
self.crypto_currencies.set( set() )
File "/Users/davea/Documents/workspace/cbapp/venv/lib/python3.9/site-packages/django/db/models/fields/related_descriptors.py
", line 536, in __get__
return self.related_manager_cls(instance)
File "/Users/davea/Documents/workspace/cbapp/venv/lib/python3.9/site-packages/django/db/models/fields/related_descriptors.py
", line 846, in __init__
self.core_filters[core_filter_key] = getattr(instance, rh_field.attname)
File "/Users/davea/Documents/workspace/cbapp/venv/lib/python3.9/site-packages/django/db/models/query_utils.py", line 142, in
__get__
val = self._check_parent_chain(instance)
File "/Users/davea/Documents/workspace/cbapp/venv/lib/python3.9/site-packages/django/db/models/query_utils.py", line 158, in
_check_parent_chain
return getattr(instance, link_field.attname)
AttributeError: 'NoneType' object has no attribute 'attname'
How do I properly set my many-to-many field with the values from my array?
Edit: Per the advice given, I tried creating a separate method for creating the account and then the set, but this
def create_account(self, user, vendor, crypto_currencies_arr=[], max_transactions=DEFAULT_MAX_BUY_TRANSACTIONS):
a = Account(
user=user,
vendor=vendor,
max_transactions=max_transactions
)
a.save()
cc_set = set()
for cc in crypto_currencies_arr:
cc_set(cc)
a.crypto_currencies = cc_set
a.save()
results in the error
cc_set(cc)
TypeError: 'set' object is not callable
From your edit, if crypto_currencies_arr contains a list of CryptoCurrency instances with primary keys, then you can just do:
def create_account(self, user, vendor, crypto_currencies_arr=[], max_transactions=DEFAULT_MAX_BUY_TRANSACTIONS):
a = Account.objects.create(
user=user,
vendor=vendor,
max_transactions=max_transactions,
)
a.crypto_currencies.set(crypto_currencies_arr)
I have a django view that causes FOREIGN KEY constraint failed. This is coming from a related question
def return_book(request,pk):
books = Books.objects.filter(school = request.user.school).get(id = pk)
book = Issue.objects.get(book_id_id=pk,book_id__school_id = request.user.school.id)
user = CustomUser.objects.get(id=request.user.id)
Return.objects.create(borrowed_item_id=book.id,returner=user)
Books.Addbook(books)
Issue.objects.get(book_id_id=pk).delete()
return redirect("view_books")
The erro is returned at Issue.objects.get(book_id_id=pk).delete()
I don't know the exact cause of this error. Could somebody explain to me what's going on hat causes the error>
The Traceback is below.
Traceback (most recent call last):
File "C:\Users\FR GULIK\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
response = get_response(request)
File "C:\Users\FR GULIK\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\core\handlers\base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\FR GULIK\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\contrib\auth\decorators.py", line 21, in _wrapped_view
return view_func(request, *args, **kwargs)
File "D:\Python\Django\test projects\library manage\lib_system\Library-System\libman\views.py", line 209, in return_book
Issue.objects.get(book_id_id=pk).delete()#Borrower_id is also required in the filter
File "C:\Users\FR GULIK\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\db\models\base.py", line 947, in delete
return collector.delete()
File "C:\Users\FR GULIK\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\db\models\deletion.py", line 396, in delete
count = sql.DeleteQuery(model).delete_batch([instance.pk], self.using)
File "C:\Users\FR GULIK\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\db\models\sql\subqueries.py", line 43, in delete_batch
num_deleted += self.do_query(self.get_meta().db_table, self.where, using=using)
File "C:\Users\FR GULIK\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\db\models\sql\subqueries.py", line 23, in do_query
cursor = self.get_compiler(using).execute_sql(CURSOR)
File "C:\Users\FR GULIK\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\db\models\sql\compiler.py", line 1156, in execute_sql
cursor.execute(sql, params)
File "C:\Users\FR GULIK\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\db\backends\utils.py", line 98, in execute
return super().execute(sql, params)
File "C:\Users\FR GULIK\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\db\backends\utils.py", line 66, in execute
return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File "C:\Users\FR GULIK\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\db\backends\utils.py", line 75, in _execute_with_wrappers
return executor(sql, params, many, context)
File "C:\Users\FR GULIK\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\db\backends\utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "C:\Users\FR GULIK\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\db\utils.py", line 90, in __exit__
raise dj_exc_value.with_traceback(traceback) from exc_value
File "C:\Users\FR GULIK\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\db\backends\utils.py", line 84, in _execute
return self.cursor.execute(sql, params)
File "C:\Users\FR GULIK\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\db\backends\sqlite3\base.py", line 413, in execute
return Database.Cursor.execute(self, query, params)
django.db.utils.IntegrityError: FOREIGN KEY constraint failed
class Issue(models.Model):
borrower_id = models.ForeignKey(Student,on_delete=models.CASCADE)
book_id = models.ForeignKey(Books,on_delete=models.CASCADE)
issue_date = models.DateField(default=datetime.date.today)
issuer = models.ForeignKey(CustomUser,on_delete=models.CASCADE)
class Return(models.Model):
return_date = models.DateField(default=datetime.date.today)
borrowed_item = models.ForeignKey(Issue,on_delete=models.DO_NOTHING)
returner = models.ForeignKey(CustomUser,on_delete=models.DO_NOTHING)
Do DO_NOTHING is typically not a good option since (most) databases will check referential integrity. This means that they guarantee that if a ForeignKey refers (in this case to an Issue), then that means that the table that stores the issues should have a record with the primary key the Return item refers to.
Often DO_NOTHING is used in combination with a certain trigger in the database system (that Django is not aware of).
Typically the most popular choices foron_delete are:
models.CASCADE: in that case it will remove all Returns related to the removed item;
models.PROTECT: in that case it will raise an error to prevent removing the Issue; and
models.SET_NULL: this is done on a NULLable field (so with null=Ture), in which case the impacted Return(s) will set the field to NULL/None.
Another option might be to "soft delete" records, for example with the django-soft-delete package [pypi]. In that case a boolean is added to the Issue that specifies if the item is removed. The package will also transparently filter the objects, such that you only retrieve records that are "alive".
This edge case is not directly relevant for the OP, but may help others that wind up here based on the title:
An IntegrityError: FOREIGN KEY constraint failed will also be raised when trying to delete some object x, if there is a table in your database that Django is unaware of, and this table has a reference to object x.
This can happen, for example, if you remove a model from your code without properly migrating the changes.
As a result, the table remains in the database, but Django does not know anything about it, so, when object x is deleted, Django does not know it should also delete the corresponding row from this "orphaned" table.
It seems like all no error in the code but no idea why I'm getting this.
I was creating a simple GUI app which store user details to a database(postgresql) and also they will be able to search for entries in database. This particular error ocures in this search() function so I haven't added the rest of the code. If necessary I can add them.
Hope I will get some solutions from this community.
def search(id):
conn = psycopg2.connect(dbname="postgres",user="postgres",password="1018",host="localhost",port="5432")
mycursor = conn.cursor()
query = '''select * from demotab where id=%s '''
mycursor.execute(query, (id))
row = mycursor.fetchone()
print(row)
conn.commit()
conn.close()
Getting this error below
Exception in Tkinter callback
Traceback (most recent call last):
File "c:\programdata\anaconda3\lib\tkinter\__init__.py", line 1702, in __call__
return self.func(*args)
File "appwithDB.py", line 51, in <lambda>
search_button = Button(newframe, text="Search", command=lambda : search(entry_search.get()))
File "appwithDB.py", line 71, in search
mycursor.execute(query, (id))
TypeError: not all arguments converted during string formatting
The second argument to mycursor.execute must be an iterable containing the values to insert in the query
You can use a list: mycursor.execute(query, [id])
or a one-element tuple: mycursor.execute(query, (id,))
Notice the comma. (id) is the same than id. In python, the comma is making the tuple, not the parenthesis.
This error is thrown up when "hr.employee" or any other model with
Many2many field is inherited to my model in odoo13.
Traceback (most recent call last):
File "/opt/odoo/odoo/modules/registry.py", line 59, in __new__
return cls.registries[db_name]
File "/opt/odoo/odoo/tools/func.py", line 69, in wrapper
return func(self, *args, **kwargs)
File "/opt/odoo/odoo/tools/lru.py", line 44, in __getitem__
a = self.d[obj].me
KeyError: 'shorepoint'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/opt/odoo/odoo/modules/registry.py", line 85, in new
odoo.modules.load_modules(registry._db, force_demo, status, update_module)
File "/opt/odoo/odoo/modules/loading.py", line 423, in load_modules
registry.setup_models(cr)
File "/opt/odoo/odoo/modules/registry.py", line 247, in setup_models
model._setup_fields()
File "/opt/odoo/odoo/models.py", line 2684, in _setup_fields
field.setup_full(self)
File "/opt/odoo/odoo/fields.py", line 418, in setup_full
self._setup_regular_full(model)
File "/opt/odoo/odoo/fields.py", line 3151, in _setup_regular_full
raise TypeError(msg % (self, field))
TypeError: Many2many fields school.student.category_ids and hr.employee.category_ids use the same table and columns
Here is my code:
from odoo import models, fields, api
class school_management(models.Model):
_name = 'school.student'
_inherit = 'hr.employee'
_description = 'Model to manage school students'
In hr application the field category_ids was defined like this:
category_ids = fields.Many2many(
'hr.employee.category', 'employee_category_rel',
'emp_id', 'category_id',
string='Tags')
they specified the name of relation and columns so when he inherited the hr.employee in your custom model the same definition of category_ids is used for your model, this why Odoo is confused you used the same relation and columns to define a many2many relation for two different model. all you have to do is remove this ambiguity by specifying a new relation name for you many2many field.
class school_management(models.Model):
_name = 'school.student'
_inherit = 'hr.employee'
_description = 'student' # this will be used to log message when you create a student, so keep it simple, when you create a record message will be 'student is created'
# define new relation name and better column names
# and I think you need a new category model because this one is used for employee category, may be it's better to create hr.student.category table I don't know it's up to you
category_ids = fields.Many2many(
'hr.employee.category', 'student_category_rel',
'student_id', 'category_id',
string='Tags')
I hope this helps you.
for me I had the same issue, the above comment about naming the realtion and other relations columns solved this, but after that I had to put the modules which have the realtion models in my module dependencies so it can create a new table for this relation in database.
I would like to specify a schema field wichi accepts one or many resources. However I seem only able to specify one behavior or the other.
>>> class Resource(marshmallow.Schema):
... data = marshmallow.fields.Dict()
...
>>> class ContainerSchema(marshmallow.Schema):
... resource = marshmallow.fields.Nested(ResourceSchema, many=True)
...
>>> ContainerSchema().dump({'resource': [{'data': 'DATA'}]})
MarshalResult(data={'resource': [{'data': 'DATA'}]}, errors={})
In the above example a list must be defined. However I would prefer not to:
>>> ContainerSchema().dump({'resource': {'data': 'DATA'}})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/lib64/python3.6/site-packages/marshmallow/schema.py", line 513, in dump
**kwargs
File "/lib64/python3.6/site-packages/marshmallow/marshalling.py", line 147, in serialize
index=(index if index_errors else None)
File "/lib64/python3.6/site-packages/marshmallow/marshalling.py", line 68, in call_and_store
value = getter_func(data)
File "/lib64/python3.6/site-packages/marshmallow/marshalling.py", line 141, in <lambda>
getter = lambda d: field_obj.serialize(attr_name, d, accessor=accessor)
File "/lib64/python3.6/site-packages/marshmallow/fields.py", line 252, in serialize
return self._serialize(value, attr, obj)
File "/lib64/python3.6/site-packages/marshmallow/fields.py", line 448, in _serialize
schema._update_fields(obj=nested_obj, many=self.many)
File "/lib64/python3.6/site-packages/marshmallow/schema.py", line 760, in _update_fields
ret = self.__filter_fields(field_names, obj, many=many)
File "/lib64/python3.6/site-packages/marshmallow/schema.py", line 810, in __filter_fields
obj_prototype = obj[0]
KeyError: 0
Can I have a schema allowing both a single item or many of it?
The point with giving the arguments as a list - whether it's one or many - is so the schema knows how to handle it in either case. For the schema to process arguments of a different format, like not in a list, you need to add a preprocessor to the schema, like this:
class ContainerSchema(marshmallow.Schema):
resource = marshmallow.fields.Nested(ResourceSchema, many=True)
#pre_dump
def wrap_indata(self, indata):
if type(indata['resource']) is dict:
indata['resource'] = [indata['resource']]