I am migrating to a new database with SQLAlchemy and want to create the database and tables using db.create_all(). Now I am getting the following error
psycopg2.errors.UndefinedTable: relation "Image" does not exist
when I am trying to import db. The error occurs because I'm creating a global variable a service of the app depends on by executing a query Image.query.all(). So practically, the variable is created when the app starts. Of course this does not work now because the data structure is not yet in place.
How can I get around this issue without having to temporarily commenting out the code? Basically I want to simply be able to conduct the database setup without this query being executed.
Related
Is there a way to delete or modify a table using flask-sqlalchemy?
I am working on a Flask-based web app. I switched to flask-sqlalchemy as my project is on Heroku and I had to connect my table to Heroku PostgreSQL. I made a flask-sqlalchemy table and created it using the db.create_all() command.
Now, for my app to fulfill its purpose, it is of utmost importance to save images, the best way of which I found to be to add them to the database.
Now, I want to change the particular table class to store a column called image as image = db.Column(db.Text, nullable=False) but I cannot. The former schema is unchanged and it gives me an error signifying that the column image does not exist every time I try to access or add something to the table.
How to do this?
You can use drop()
from sqlalchemy import create_engine
engine = create_engine("...")
my_table.__table__.drop(engine)
For a specific security reason, a client has asked if we can integrate a 'write-only' DB into a Django web application. I have tried creating a DB then restricting access to one of its tables in psql via:
REVOKE SELECT ON TABLE testapp_testmodel FROM writeonlyuser;
But then trying to save a model in the Django shell...
p = new TestModel(test_field="testvalue")
p.save(using="writeonlydb")
...generates this error:
ProgrammingError: permission denied for relation testapp_testmodel
Which I assume is because the ORM generated SQL includes a return of the newly created object's id, which counts as a read:
INSERT INTO "testapp_testmodel" ("test_field") VALUES ('testvalue') RETURNING "testapp_testmodel"."id"
My question is therefore, is this basically impossible? Or is there perhaps some other way?
I'm using Django Python framework, and MySQL DBMS.
In the screenshot below, I'm creating the new_survey_draft object using the SurveyDraft.objects.create() as shown, assuming that it should create a new row in the surveydraft DB table, but as also shown in the screenshot, and after debugging my code, the new_survey_draft object was created with id=pk=270 , while the DB table shown in the other window to the right doesn't have the new row with the id=270.
Even when setting a break point in the publish_survey_draft() called after the object instantiation, I called the SurveyDraft.objects.get(pk=270) which returned the object, but still there is not id=270 in the DB table.
And finally, after resuming the code and returning from all definitions, the row was successfully added to the DB table with the id=270.
I'm wondering what's happening behind the seen, and is it possible that Django stores data in objects without persisting to DB on real-time, and only persists the data all together on some later execution point?
I've been stuck in this for hours and couldn't find anything helpful online, so I really appreciate any advice regarding the issue.
After digging deep into this issue, I just found that there is a concept called Atomic Requests that's enabled in my Django project by setting the ATOMIC_REQUESTS to True in the settings.py under the DATABASES dictionary as explained here
It works like this. Before calling a view function, Django starts a
transaction. If the response is produced without problems, Django
commits the transaction. If the view produces an exception, Django
rolls back the transaction.
That's why the changes were not persisting in the database while debugging my code using break points, since the changes will only be committed to the DB once the successful response is returned.
I have a postgreSQL database that has a table foo that I've created outside of django. I used manage.py inspectdb to build the model for table foo for me. This technique worked fine when I was using MySQL but with PostgreSQL it is failing MISERABLY. The table is multiple gigabytes and I build it from a text file with PostgreSQL 'COPY'.
I can run raw queries on table foo and everything executes and expected.
For example
foo.objects.raw('bar_sql')
executes as expected.
But running queries like:
foo.objects.get(bar=bar)
throw
ProgrammingError column foo.id does not exist LINE 1: SELECT "foo"."id", "foo"."bar1", "all_...
foo doesn't innately have an id field. As I understand it django is suppose to create one. Have I some how subverted this step when creating the tables outside of django?
Queries run on models whose table was populated threw django run as expected in all cases.
I'm missing something very basic here and any help would be appreciated.
I'm using django 1.6 with postgreSQL 9.3.
Django doesn't modify your existing database tables. It only creates new tables. If you have existing tables, it usually doesn't touch them at all.
"As I understand it django is suppose to create one." --> It only adds a primary key to a table when it creates it, which means you don't need to specify that explicitly in your model, but it won't do anything to an existing table.
So if for example you later on decide to add fields to your models, you have to update your databases manually.
What you need to do in your case is that by doing manual database administration make sure that your table has a primary key, and also that the name of the primary key is "id" (although I am not sure if this is necessary, it is better to do it.) So use a database administration tool, modify your table and add the primary key, and name it id. Then it should start working.
I am a little confused with the topic alluded to in the title.
So, when a Flask app is started, does the SQLAlchemy search theSQLALCHEMY_DATABASE_URI for the correct, in my case, MySQL database. Then, does it create the tables if they do not exist already?
What if the database that is programmed into theSQLALCHEMY_DATABASE_URI variable in the config.py file does not exist?
What if that database exists, and only a few of the tables exist (There are more tables coded into the SQLAlchemy code than exist in the actual MySQL database)? Does it erase those tables and then create new tables with the current specs?
And what if those tables do all exist? Do they get erased and re-created?
I am trying to understand how the entire process works so that I (1) Don't lose database information when changes are made to the schema, and (2) can write the necessary code to completely manage how and when the SQLAlchemy talks to the actual Database.
Tables are not created automatically; you need to call the SQLAlchemy.create_all() method to explicitly to have it create tables for you:
db = SQLAlchemy(app)
db.create_all()
You can do this with command-line utility, for example. Or, if you deploy to a PaaS such as Google App Engine, a dedicated admin-only view.
The same applies for database table destruction; use the SQLAlchemy.drop_all() method.
See the Creating and Dropping tables chapter of the documentation, or take a look at the database chapter of the Mega Flask Tutorial.
You can also delegate this task to Flask-Migrate or similar schema versioning tools. These help you record and edit schema creation and migration steps; the database schema of real-life projects is never static and you would want to be able to move existing data between versions or the schema. Creating the initial schema is then just the first step.