I am working allong with Django book. Now I'm on the fifth chapter(Models) and right now I'm dealing with some problems. For instance, when I'm trying to write in my shell: python.py manage.py sqlall my_app_name I am getting this message:
Where is my mistake?
P.S. My my_app.models.py:
from django.db import models
class Publisher(models.Model):
name = models.CharField(max_length=30)
address = models.CharField(max_length=50)
city = models.CharField(max_length=60)
state_province = models.CharField(max_length=30)
country = models.CharField(max_length=50)
website = models.URLField()
class Author(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email = models.EmailField()
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
publisher = models.ForeignKey(Publisher)
publication_date = models.DateField()
My project settings.py databases configuration:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'mydb',
'USER': 'admin', # Not used with sqlite3.
'PASSWORD': '123', # Not used with sqlite3.
'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
'PORT': '', # Set to empty string for default. Not used wit
}
}
And finally - my project settings.py INSTALLED_APPS and MIDDLEWARE_CLASSES:
INSTALLED_APPS = (
#'django.contrib.admin',
#'django.contrib.auth',
#'django.contrib.contenttypes',
#'django.contrib.sessions',
#'django.contrib.messages',
#'django.contrib.staticfiles',
'books', # MY APP NAME
)
MIDDLEWARE_CLASSES = (
#'django.contrib.sessions.middleware.SessionMiddleware',
#'django.middleware.common.CommonMiddleware',
#'django.middleware.csrf.CsrfViewMiddleware',
#'django.contrib.auth.middleware.AuthenticationMiddleware',
#'django.contrib.messages.middleware.MessageMiddleware',
#'django.middleware.clickjacking.XFrameOptionsMiddleware',
)
If you need any more information just say. Thank you in advance!
The error message is quite explicit that this is a problem with connecting to the database with that username and password. Have you set that account up in Postgres?
Related
I'm not new to Python nor Django, but this is the first time I'm creating a completely new big project from scratch, and also the first time I'm actually creating the models for the whole database and I'm kinda confused here.
Does Django does not really create the ForeignKey constraints on the Database to check if ID exists? It is just a logical python thing that works only when the server is running? Or is it a problem that happens on MySQL?
Just to be clear what I'm talking about, the first thing I noticed because as a Laravel developer on PHP side, I'm used to always check the database diagram that PhpStorm/PyCharm generates by connecting to the database, and on Laravel migrated tables, we can see the arrows pointing to the respective foreign key tables relationships, but on the Django created database there is not a single arrow on the database diagram generated by the JetBrains IDE. So I went testing.
For example, I have the following models:
class Series(models.Model):
class Meta:
app_label = 'core'
db_table = 'km_series'
verbose_name_plural = 'series' # added this to avoid plural being "seriess"
name = models.CharField(max_length=200)
description = models.TextField(default=None, blank=True, null=True)
cover_img = models.CharField(max_length=100, default=None, blank=True, null=True)
on_going = models.BooleanField(default=False)
date_added = models.DateTimeField(auto_now_add=True)
date_updated = models.DateTimeField(auto_now=True)
def __str__(self):
return "{} - ID #{}".format(self.name, self.id)
class Chapter(models.Model):
class Meta:
app_label = 'core'
db_table = 'km_chapter'
series = models.ForeignKey(Series, on_delete=models.CASCADE)
number = models.IntegerField(validators=[MinValueValidator(0)])
name = models.CharField(max_length=150, default=None, blank=True, null=True)
date_added = models.DateTimeField(auto_now_add=True)
date_updated = models.DateTimeField(auto_now=True)
def __str__(self):
return "#{} - {}".format(self.number, self.name)
I have more than 15 models created already using models.ForeignKey along other fields. I just tried creating a new row on MySQL using the python manage.py shell.
$ python manage.py shell
>>> from core.models import *
>>> Series
<class 'core.models.base_models.Series'>
>>> one = Series.objects.create(name='Test')
>>> one
<Series: Test - ID #1>
>>> one.id
1
>>> chapter = Chapter.objects.create(number=1)
MySQLdb.OperationalError: (1048, "Column 'series_id' cannot be null")
>>> chapter = Chapter.objects.create(number=1, series_id=2)
>>> chapter
<Chapter: #1 - None>
>>> chapter_1 = Chapter.objects.create(number=1, series=one)
>>> chapter_1
<Chapter: #1 - None>
>>> chapter = Chapter.objects.create(number=1, series_id=25)
There is only one ID on database, where the ID is "1"
So how can I be able to add any ID when manually assigning, and not passing the whole instantiated object as foreign_key value?
Why Django allows me to set the ID to non-existing IDs on the database? Shouldn't this result in an error? Am I missing something on my models? Why there is no constraint and validations for this kind of thing?
After digging a little on why MySQL would have a problem with FK contraints, and after using the python manage.py dbshell command to check the table creation as I was recommended doing on a comment, by using SHOW CREATE TABLE core_chapter; , I discovered the problem.
For some reason that I don't really know why, my Database was created using MyISAM, which is a MySQL storage engine that does not support FK constraints. I had to change the default to InnoDB, as it works with this types of validations for relationships between tables.
On my my.cnf file which holds the confs for MySQL, I enforced InnoDB as default by adding the default-storage-engine property
[mysqld]
default-storage-engine = InnoDB
And on Django settings, I also added the DATABASE "OPTIONS", as stated on the Django documentation for databases, so my DATABASES value was changed to:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'database_name',
'USER': 'database_user',
'PASSWORD': '****',
'HOST': 'localhost',
'PORT': '3306',
'OPTIONS': {'init_command': 'SET default_storage_engine=INNODB'},
}
}
After changing all that, dropping all database tables and then calling the python manage.py migrate again, the constraints were created as expected, and now my PyCharm generated database diagram shows all the arrows showing the relationships flawlessly.
I'am using MySQL and PostgreSQL in my Django project. Below are the settings:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'mysql_db',
'USER': 'username',
'PASSWORD': 'password',
'HOST': 'hostname',
'PORT': '3306',
},
'postgres_db': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'pgsql_db',
'USER': 'username',
'PASSWORD': 'password',
'HOST': 'hostname',
'PORT': '5432',
}
}
And this is the sample model
from postgres_copy import CopyManager
class Items(models.Model):
class params:
db = "postgres_db"
sales_value = models.CharField(max_length=255, null=True, blank=True)
primary_email = models.CharField(max_length=255, null=True, blank=True)
objects = CopyManager()
I want to use Items.objects.all().to_csv('./path/to/csv) this ORM to export model data to CSV. I have used this before in exporting large dataset to csv.
But in this configuration it gives below error
psycopg2.errors.SyntaxError: syntax error at or near "."
LINE 1: COPY (SELECT `sales_item`.`id`, `sales_item`.`sales_value`,...
This seems to be an issue with multiDB.
If I run this ORM in single DB configuration, or even if I set default alias on PostgreSQL this works fine.
CopyManager seems to be getting default alias somehow which I have no idea about.
How can I run this ORM in current settings without any issues?
Any help would be appreciated.
Thanks in advance.
We use postgres and MariaDB in the same time in one project.
I can say - you dont need any additional data manager, in your case it can be:
from django.db.import models
class ItemsQuerySetManager(models.Manager):
def get_queryset(self, *args, **kwargs):
return super().get_queryset(*args, **kwargs).using("postgres_db")
class Items(models.Model):
sales_value = models.CharField(max_length=255, null=True, blank=True)
primary_email = models.CharField(max_length=255, null=True, blank=True)
objects = ItemsQuerySetManager()
more info here: https://docs.djangoproject.com/en/4.1/topics/db/multi-db/
I tried to start using Postgresql instead of sqlite in my Django project.
I installed postgreqL ON MY Windows, creatred a new database, user and password.
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'database_name',
'USER': 'admin',
'PASSWORD': 'admin',
'HOST': 'localhost',
'PORT': '5432',
}
}
But when I try to migrate or makemigrations, I got this:
File
"C:\Users\s...\venv\lib\site-packages\django\db\backends\utils.py",
line 85, in _execute
return self.cursor.execute(sql, params) psycopg2.errors.UndefinedTable: relation "authentication_author" does
not exist LINE 1: ...hentication_author"."is_doctor" FROM
"authentic...
here is my model:
class Author(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, null=True, related_name="author")
slug = models.CharField(max_length=50, null=True, blank=True,)
is_doctor = models.BooleanField(default=False)
And yes, I deleted the sqlite3 database, all the migrations folders and I created new ones with the init.py inside of them.
But still get the same problem.
Updated
Traceback screenshots:
It happens with Django. Sometimes you can invoke some code that relies on a new DB schema at the time you're trying to makemigrations.
All you need in this situation is to temporarily comment out all the code that connects makemigrations with your new model's schema. As it was in this question, you can trace related blocks of code just using full traceback.
I'm trying to read values from an sqlite db I added to my Django project but it doesn't work.
I did a test in the Python shell and all it returned was the following error when I tried looking into the data:
from myapp.models import my_data
my_data.objects.all()
OperationalError: no such column: my_table_name.id
This is how my models.py file looks like:
class my_data(models.Model):
status = models.TextField(db_column='STATUS', blank=True, null=True)
name_1 = models.TextField(db_column='NAME_1', blank=True, null=True)
name_2 = models.TextField(db_column='NAME_2', blank=True, null=True)
dep = models.IntegerField(db_column='DEP', blank=True, null=True)
name_reg = models.TextField(db_column='NAME_REG', blank=True, null=True)
reg = models.IntegerField(db_column='REG', blank=True, null=True)
name_com = models.TextField(db_column='NAME_COM', blank=True, null=True)
avgp = models.IntegerField(db_column='AVGP', blank=True, null=True)
class Meta:
managed = True
db_table = 'my_table_name'
My settings.py file:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
},
'my_table_name': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db_my_table_name.sqlite3'),
}
}
Also, I performed the python manage.py makemigrations and python manage.py migrate commands.
Any idea what I am doing wrong?
I write this according to this comment since you said it worked:
Add a id field to my_data model:
AutoField like: id = models.AutoField(primary_key=True)
Tip: In django model names should follow CamelCase convention.
I had the same issue before then i used the below code for my models.py file, this has resolved the issue
class ModelName(models.Model):
id = models.AutoField(primary_key=True)
This could help you to resolve the above Problem
Add this in your models.py:
id = models.AutoField(primary_key=True)
I created a simple test case like this:
from unittest import TestCase
import user_manager
class UserTest(TestCase):
def test_register(self):
email = "dung7#gmail.com"
password = "123456"
result, user = user_manager.setup_new_user(email, password)
self.assertEqual(result, CodeID.SUCCESS)
Then I run the testcase:
python manage.py test users
And here is the log:
Creating test database for alias 'default'...
/Users/admin/Projects/MyApp/venv/lib/python2.7/site-packages/django/db/backends/mysql/base.py:112: Warning: Table 'mysql.column_stats' doesn't exist
return self.cursor.execute(query, args)
Creating test database for alias 'myapp_log'...
.FE
======================================================================
ERROR: test_register (users.tests.UserTest)
----------------------------------------------------------------------
Traceback (most recent call last):
...
ProgrammingError: (1146, "Table 'test_myapp.user' doesn't exist")
So it created a test database but seem like it didn't create the tables. Here is my DATABASES setting:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': "myapp",
'USER': "root",
'PASSWORD': "",
'HOST': '127.0.0.1',
'PORT': '',
},
'myapp_log': {
'ENGINE': 'django.db.backends.mysql',
'NAME': "myapp_log",
'USER': "root",
'PASSWORD': "",
'HOST': '127.0.0.1',
'PORT': '',
},
}
And my model:
class User(BaseModel):
uid = models.IntegerField(primary_key=True)
email = models.CharField(max_length=200)
password = models.CharField(max_length=200)
create_time = models.IntegerField()
update_time = models.IntegerField()
status = models.IntegerField()
social_token = models.CharField(max_length=200)
social_app = models.IntegerField()
class Meta:
db_table = 'user'
Anyone know why the table 'user' is not created?
UPDATE:
user_manager from my testcase will do some query and add new record on table user.
And I thought when I run the testcase, Django will somehow read my models and create a test database with all the table from those models. Am I right about this?
So I found out I need to put my models.py in my users' folder and add 'users' into the INSTALLED_APPS setting. Now it worked.
Your test database needs to be different than your production database. Test databases are destroyed once the test cases are run. In your case the database was not created. You should go through this documentation for detailed information https://docs.djangoproject.com/en/1.10/topics/testing/overview/
Can you also add the snippet of your user_manager module