I am stuck connecting to my database. I'm not sure why the error as follows keep coming out even though I've followed the documentation clearly.
sqlalchemy.exc.InterfaceError: (pyodbc.InterfaceError) ('IM002', '[IM002] [Microsoft][ODBC Driver Manager] Data source name not found and no default driver specified (0) (SQLDriverConnect)')
My connection string looks like this
from flask import Flask, request, jsonify
from flask_sqlalchemy import SQLAlchemy
from flask_marshmallow import Marshmallow
from sqlalchemy import desc, create_engine
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mssql+pyodbc://localhost\SQLEXPRESS/master?driver=ODBC Driver 17 for SQL Server?Trusted_Connection=True'
app.config['SQLALCEHMY_MODIFICATIONS'] = False
db = SQLAlchemy()
ma = Marshmallow()
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100))
description = db.Column(db.String(200))
author = db.Column(db.String(50))
def __init__(self, title, description, author):
self.title = title
self.description = description
self.author = author
class PostSchema(ma.Schema):
class Meta:
fields = ("title", "description", "author")
post_schema = PostSchema()
posts_schema = PostSchema(many=True)
#app.route('/', methods=['GET'])
def get_post():
return jsonify({"Hello": "World"})
#app.route('/post', methods=['POST'])
def add_post():
title = request.json['title']
description = request.json['description']
author = request.json['author']
my_post = Post(title, description, author)
db.session.add(my_post)
db.session.commit()
return post_schema.jsonify(my_post)
db.init_app(app)
ma.init_app(app)
if __name__ == "__main__":
app.run(debug=True)
Is there anywhere in which I left out? Whenever I tried to create a post request through postman, it will show the error as stated above. I am sure the ODBC driver exist and I've connected it to the local database that I have installed in my PC. Also, table Post is already created on my database such as follows:
USE [master]
GO
/****** Object: Table [dbo].[Post] Script Date: 23-Mar-22 1:30:52 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Post](
[id] [int] IDENTITY(1,1) NOT NULL,
[title] [nvarchar](200) NULL,
[description] [nvarchar](200) NULL,
[author] [nvarchar](200) NULL,
CONSTRAINT [PK_ID] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO
Thanks for any suggestions
As reviewed, The connection URI was missing escape of the backslash and '&' instead of '?' symbol. Thanks for the suggestions.
Related
sqlalchemy.exc.OperationalError
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table: blogpost [SQL: 'INSERT INTO blogpost (title, author, date_posted, content) VALUES (?, ?, ?, ?)'] [parameters: ('qedqdq', 'qwdqdwd', '2018-12-31 22:51:35.669388', 'qwdqwdqwdqwdqwdqwdqwdqwdw')] (Background on this error at: http://sqlalche.me/e/e3q8)
After i send the post to get published in my database i get ^^ the error
here are some of the code i am using.
Any help would be great thanks!!!
app.py
import os
from flask import Flask, render_template, request, redirect, url_for
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URL'] = 'sqlite:///Users/------/Desktop/face0/face/blog.db'
db = SQLAlchemy(app)
class Blogpost(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(50))
author = db.Column(db.String(20))
date_posted = db.Column(db.DateTime)
content = db.Column(db.Text)
#app.route('/addpost', methods=['POST'])
def addpost():
title = request.form['title']
author = request.form['author']
content = request.form['content']
post = Blogpost(title=title, author=author, content=content, date_posted=datetime.now())
db.session.add(post)
db.session.commit()
return redirect(url_for('index'))
As mentioned in the flask-sqlalchemy documentation, you will need to first create the database by calling the create_all function.
To create the initial database, just import the db object from an
interactive Python shell and run the SQLAlchemy.create_all() method to
create the tables and database:
>>> from yourapplication import db
>>> db.create_all()
In your case this may look something like the following:
$ python
>>> from app import db
>>> db.create_all()
>>> exit()
I have an flask app, using flask-slqalchemy to query a mysql database
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:password#localhost/abc'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
there is a table "users" in "abc" database and it is already populated with several hundred rows.
Now i need to import this existing table, rather than first defining it with db.Model
how do i call the table?
if i do this
from sqlalchemy import Table
USERS = Table('users', db.metadata,autoload=True, autoload_with=db.engine)
then i am not able to make a query like
USERS.query.filter_by(done=1).with_entities(USERS.name,USERS.country).paginate(page, 15, False)
it generates an error
AttributeError: 'Table' object has no attribute 'query'
because this is sqlchemy command, not flask-sqlchemy, i dont fully understand this.
I have to first define the table USERS like i am creating it for the first time :
class USERS(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.VARCHAR(500))
country = db.Column(db.VARCHAR(50))
def __init__(self, id, name, country):
self.id = id
self.name = name
self.country = country
def __repr__(self):
return self.id
only then i am able to use USERS to query the database through flask-sqlalchemy
How do i access the an existing table users using flask-sqlchemy in an flask app?
In sqlalchemy you should query table(s) with session if you want to query Table(). Because 'Table' object has no attribute 'query'. And you do not need to create table if it has existed, just use it. sqlalchemy existing database query
from sqlalchemy import Table, Column, String, create_engine, MetaData
from sqlalchemy.orm import sessionmaker
engine = create_engine()
metadata = MetaData()
test_ = Table('test', metadata,
Column('msg', String, primary_key=True),
Column('msg_', String)
)
Session = sessionmaker(bind=engine)
session = Session()
print(session.query(test_).filter_by(msg_ = "test").with_entities("msg","msg_").one())
# ('t', 'test')
In flask_sqlalchemy, it almost same as sqlalchemy did.
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = ""
db = SQLAlchemy(app)
class test(db.Model):
msg = db.Column(db.String, primary_key=True)
msg_ = db.Column(db.String)
def __init__(self, msg, msg_):
self.msg = msg
self.msg_ = msg_
def __repr__(self):
return "msg: {} msg_: {}".format(self.msg,self.msg_)
result = test.query.filter_by(msg_="test").one()
print(result)
print(result.msg,result.msg_)
'''
msg: t msg_: test
t test
'''
Minimal example:
models.py
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class Patient(db.Model):
id = db.Column(db.Integer, primary_key=True)
notes = db.relationship("Note", backref=db.backref("patient", lazy=True))
class Note(db.Model):
id = db.Column(db.Integer, primary_key=True)
patient_id = db.Column(db.Integer, db.ForeignKey("patient.id"), nullable=False)
app.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.secret_key = "super secret"
POSTGRES = {
"user": "postgres",
"pw": "password",
"db": "test_db",
"host": "localhost",
"port": "5432",
}
app.config["SQLALCHEMY_DATABASE_URI"] = "postgresql://%(user)s:%(pw)s#%(host)s:%(port)s/%(db)s" % POSTGRES
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
app.config["DEBUG"] = True
from models import db
with app.app_context():
db.init_app(app)
run.py
from app import app, db
if __name__ == "__main__":
with app.app_context():
db.create_all()
app.run()
However, I get the following error:
sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) column "id" referenced in foreign key constraint does not exist
[SQL: '\nCREATE TABLE note (\n\tid SERIAL NOT NULL, \n\tpatient_id INTEGER NOT NULL, \n\tPRIMARY KEY (id), \n\tFOREIGN KEY(patient_id) REFERENCES patient (id)\n)\n\n'] (Background on this error at: http://sqlalche.me/e/f405)
It seems to work when I define the table with the foreign key in a psql console. What's going wrong?
I tried your sample code (I had to add the app initialisation to app.py so your code would run as-is). It worked as expected and both the note and patient tables were created.
This tells me that your issue is environmental. I'm willing to bet that if you created a brand new test database in your Postgres instance and ran your example code it would work for you too.
So let's focus on the state of the database you're connecting to.
The ProgrammingError exception you're getting shows an error coming from Postgres itself. It's saying that it can't create the notes table because there's no such foreign key as patient.id. This is probably throwing you off because you know you are defining a patient.id key in models.py. Unfortunately I don't have enough information from what you've posted to give you a definitive answer, but my guess is this:
The patient table in Postgres may have already been created from a previous run, but with a different schema (e.g. maybe it was first defined without an id column). the create_all() function will create tables that don't exist in the target database, but will not update existing tables with a modified schema.
Go check your Postgres DB and take a look at the patient table. Does it actually have an id column that is properly defined as a primary key?
If there's no data in these tables that you need, try dropping them and running your app again. My guess is that it will create both tables correctly and throw no errors.
I am developing a Flask-sqlalchemy application and using mySql database. I have a form from where I receive data to be stored in database table named "intent". The table has 2 columns: intent_id & intent_name.
Here is code for my SqlAlchemy Model:
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class Intent(db.Model):
__tablename__ = 'intent'
intent_id = db.Column('intent_id', db.Integer, primary_key=True)
intent_name = db.Column(db.String(250))
Here is code for my Flask Routes file:
from flask import Flask, render_template, request, session, redirect, url_for
from models import db, Intent, Sentence
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:#localhost/test'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db.init_app(app)
#app.route("/", methods = ['POST', 'GET'])
def index():
if request.method == 'POST':
intentobj = Intent(intent_name = request.form['intent'])
db.session.add(intentobj)
db.session.commit()
return render_template("index.html", intent_data = Intent.query.all())
elif request.method == 'GET':
return render_template("index.html", intent_data = Intent.query.all())
I am getting this error :
sqlalchemy.exc.IntegrityError: (_mysql_exceptions.IntegrityError) (1364, "Field 'intent_id' doesn't have a default value") [SQL: 'INSERT INTO intent (intent_name) VALUES (%s)'] [parameters: ('def',)]
When I create an object of my Database Table's Class, I only store intent_name in it (as given above). I expect the intent_id to auto-increment and store in database as it's a primary key but it isn't working that way, I guess.
Note that I created the table using phpmyadmin and not through python.
Please help me remove this error. Thanks.
I don't think mysql automatically incrrements a primary key.
Add autoincrement=True to the column statement
intent_id = db.Column('intent_id', db.Integer, primary_key=True, autoincrement=True)
Or, since you are generating the code with sql directly, create the table with
intent_id int NOT NULL PRIMARY_KEY AUTO_INCREMENT
Update
The problem was with the database table; the primary key was not set to auto-increment. So, trying this command actually worked:
ALTER TABLE document MODIFY COLUMN document_id INT auto_increment
I'm trying to use search capability on flask application. It seems to be saving in database properly however query isn't returning me anything.
DATABASE MODEL:
app = Flask(__name__)
csrf = CsrfProtect(app)
csrf.init_app(app)
db = SQLAlchemy(app)
class ArticleQuery(BaseQuery, SearchQueryMixin):
pass
class latest_movies_scraper(db.Model):
query_class = ArticleQuery
__tablename__ = 'latest_movies_scraper'
id = db.Column(sa.Integer, primary_key=True)
name = db.Column(db.Unicode(255))
url = db.Column(db.Unicode(255))
image_url = db.Column(db.Unicode(255))
create = db.Column(db.DateTime, default=datetime.datetime.utcnow)
search_vector = db.Column(TSVectorType('name'))
How i'm saving to database:
check_if_exists = latest_movies_scraper.query.filter_by(name=dictionary['title']).first()
if check_if_exists:
print check_if_exists.name
print 'skipping this...'
pass
else:
insert_to_db = latest_movies_scraper(name=dictionary['title'], url=dictionary['href'], image_url=dictionary['featured_image'])
db.session.add(insert_to_db)
db.session.commit()
How I am using search capbilitiy functionality:
name = latest_movies_scraper.query.search(u'Black Panther (2018)').limit(5).all()
Name returns empty array, but it should return me the name list instead.
ABOVE MY GOAL is to query the name from the database. It doesn't return me anything when in fact the name Black Panther 2018 exists in my database.
So the search functionality isn't working as expected.
SQLAlchemy-Searchable doesn't index existing data. This has to be done manually by performing a synchronisation. For the table definition above the code below is sufficient:
from sqlalchemy_searchable import sync_trigger
def sync_fts():
sync_trigger(db.engine, 'latest_movies_scraper', 'search_vector', ['name'])
This code would normally be part of the db management tools (Flask-Script, Click).